Technical debt or we must improve our code base quality

At this article I would tell about about one important code quality – maintenance.

  1. Problem.
  2. Two ways to solve your technical debt.
  3. Statick methods
  4. Getters and setter
  5. Avoid null.
  6. Conclusion.

Problem

In a technical world exists such fact as technical debt. It looks like we must devote time to improving maintainable code base of our product. For example, we work on the Android App. We must deliver app to the end customer as soon as possible. But it comes time, when you already do not understand what is going on in the app, there are many dependencies or redundant if – else blocks, while it is possible to make some things simpler. So to devote time to improving your code base may be a good decision. First of all, personally for you – you’ll be grateful to yourself for this while others will be grateful to you for this too. Recently I’ve read “Effective Java” by Joshua Bloch, and “Elegant Objects” by Yegor Bugaenko. These two books are opposite to each other.

Two ways to solve your technical debt

Static methods

Joshua Bloch – static method it is good, it may uses instead constructor. For example:

public class Car {
//Client of this does not may create object by this way. Only static
private Car() {
}
//Create a default car for client.
public static Car getDefaultCar() {
return new Car();
}
}
public class Car {

    //Client of this does not may create object by this way. Only static
    private Car() {
    }

    //Create a default car for client.
    public static Car getDefaultCar() {
        return new Car();
    }
}
public class Car { //Client of this does not may create object by this way. Only static private Car() { } //Create a default car for client. public static Car getDefaultCar() { return new Car(); } }

Instead it Elegant Object says us:

Static methods is evil, do not use it! But if your procedural programmer you may use it:)

Getters and setter

For many years we’ve considered getter and setter methods to be the encapsulation of the object state. But it is not true. We may influence on this internal state by setter methods. For example:

public class Cash {
private int dollars;
public Cash(int dollars) {
this.dollars = dollars;
}
//Influence on the internal state on the object
public void setDollars(int dollars) {
this.dollars = dollars;
}
public int getDollars() {
return this.dollars;
}
}
public class Cash {
    private int dollars;

    public Cash(int dollars) {
        this.dollars = dollars;
    }

    //Influence on the internal state on the object
    public void setDollars(int dollars) {
        this.dollars = dollars;
    }

    public int getDollars() {
        return this.dollars;
    }
}
public class Cash { private int dollars; public Cash(int dollars) { this.dollars = dollars; } //Influence on the internal state on the object public void setDollars(int dollars) { this.dollars = dollars; } public int getDollars() { return this.dollars; } }

t is not a good method to have mutable object, much better is to have immutable object such as java.lang.String

public class Cash {
private final Integer dollars;
public Cash(final Integer dollars) {
this.dollars = dollars;
}
public Integer usd() {
return this.dollars;
}
}
public class Cash {
    private final Integer dollars;

    public Cash(final Integer dollars) {
        this.dollars = dollars;
    }

    public Integer usd() {
        return this.dollars;
    }
}
public class Cash { private final Integer dollars; public Cash(final Integer dollars) { this.dollars = dollars; } public Integer usd() { return this.dollars; } }

In this case we don’t have an opportunity to change internal state of the object. To present a new cash we must create a new object.

Avoid null

Sometimes you have method which takes null as argument. For example:

public class FileFinder {
private final File file;
public FileFinder(final File file) {
this.file = file;
}
public List<String> findByMask(IMask mask) {
if (mask == null) {
return mask.all();
}
return mask.find(file);
}
public static void main(String[] args) {
IMask mskMask = new Mask("*.msk");
List<String> mskFiles = new FileFinder(args[0]).find(mskMask);
//Get all files
List<String> allFiles = new FileFinder(args[0]).find(null);
}
}
public class FileFinder {
    private final File file;

    public FileFinder(final File file) {
        this.file = file;
    }

    public List<String> findByMask(IMask mask) {
        if (mask == null) {
            return mask.all();
        }
        return mask.find(file);
    }

    public static void main(String[] args) {
       IMask mskMask = new Mask("*.msk");
       List<String> mskFiles = new FileFinder(args[0]).find(mskMask);

       //Get all files
       List<String> allFiles = new FileFinder(args[0]).find(null); 
    }
}
public class FileFinder { private final File file; public FileFinder(final File file) { this.file = file; } public List<String> findByMask(IMask mask) { if (mask == null) { return mask.all(); } return mask.find(file); } public static void main(String[] args) { IMask mskMask = new Mask("*.msk"); List<String> mskFiles = new FileFinder(args[0]).find(mskMask); //Get all files List<String> allFiles = new FileFinder(args[0]).find(null); } }

This code looks correct, but it has many useless words. Do not use null, use a stub object. With stub object the code above will look in the following way:

public class FileFinder {
private final File file;
public FileFinder(final File file) {
this.file = file;
}
public List<String> findByMask(IMask mask) {
return mask.find(file);
}
public static void main(String[] args) {
IMask withouAnyMask = new WithoutAnyMaskImpl();
List<String> allFiles = new FileFinder(args[0]).find(withoutAnyMask);
}
}
public class FileFinder {
    private final File file;

    public FileFinder(final File file) {
        this.file = file;
    }

    public List<String> findByMask(IMask mask) {
        return mask.find(file);
    }

    public static void main(String[] args) {
        IMask withouAnyMask = new WithoutAnyMaskImpl();
        List<String> allFiles = new FileFinder(args[0]).find(withoutAnyMask); 

    }
}
public class FileFinder { private final File file; public FileFinder(final File file) { this.file = file; } public List<String> findByMask(IMask mask) { return mask.find(file); } public static void main(String[] args) { IMask withouAnyMask = new WithoutAnyMaskImpl(); List<String> allFiles = new FileFinder(args[0]).find(withoutAnyMask); } }

For me personally the second option is more readable and understandable. Also it does not produce ugly NullPointerException.

Conclusion

I suggest reading both books to have a deeper understanding of how to improve the code quality. Also I recommend thinking about maintainability of your code base, because it is really important.

Follow me 😉

原文链接:Technical debt or we must improve our code base quality

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
No matter how you feel, get up, dress up and fight for your dreams.
无论你现在感觉如何,请起床、穿好衣服然后为你的梦想而奋斗
评论 抢沙发

请登录后发表评论

    暂无评论内容