理想的代码遵循德米特法则,并且是可测试的(依赖注入)



我正在阅读LoD之后的可测试代码,但是我的脑子里一片混乱。因此,请对这段代码提供任何指导,我将不胜感激。

public class HouseConfiguration {
    private final int noOfDoors;
    private final int noOfWindows;
    //.... And so on
    public HouseConfiguration(int noOfDoors, int noOfWindows){
        this.noOfDoors = noOfDoors;
        this.noOfWindows = noOfWindows;
        //.....
    }
        //getters for config
}
public class Contractor {
    public House buildHouse(HouseConfiguration houseConfiguration) throws Exception{
        validateHouseConfiguration(houseConfiguration);
        Window[] windows = new Window[houseConfiguration.getNoOfDoors()];
        return new House(windows);
    }
    private void validateHouseConfiguration(HouseConfiguration houseConfiguration) {
        //validation logic
    }
}
public class House {
    private Window[] windows;
    //Now as the parameters increase it becomes a problem to pass so many arguments in constructor
    public House(Window[] windows /*Also other arguments */) {
        this.windows = windows;
    }
}

现在,随着House构造函数的参数增加,使用构造函数来管理它将变得困难。会传递很多依赖项。这样做正确吗?或者是否有更好的方法来重构这些代码?

编辑:引用House构造函数参数

…随着众议院构造者的论据的增加,它将是很难用构造函数来管理它。

使用Builder模式(Effective Java项目2):

public class House {
    //these are immutable if you wish
    private final int mNumberOfWindows;
    private final int mNumberOfDoors;
    private House(HouseBuilder builder) {
        mNumberOfWindows = builder.mNumberOfWindows;
        mNumberOfDoors = builder.mNumberOfDoors;
    }
    public static class HouseBuilder {
        private int mNumberOfWindows; //set defaults here, make final and pass in builder constructor if they must be set
        private int mNumberOfDoors;
        public HouseBuilder windows(int numberOfWindows) {
            mNumberOfWindows = numberOfWindows;
            return this;
        }
        public HouseBuilder doors(int numberODoors) {
            mNumberOfDoors = numberODoors;
            return this;
        }
        public House build() {
            return new House(this);
        }
    }
    public int getNumberOfWindows() {
        return mNumberOfWindows;
    }
    public int getNumberOfDoors() {
        return mNumberOfDoors;
    }
}

用法:

    House.HouseBuilder hb = new House.HouseBuilder();
    hb.doors(4);
    hb.windows(3);
    House h = hb.build();
    House h2 = new House.HouseBuilder().doors(4)
            .windows(3).build();

我是这样做的(对不起,这是一个c#):

public interface IHouseConfiguration
{
    int noOfDoors { get; set; }
    int noOfWindows { get; set; }
    bool IsValid();
}
public class HouseConfiguration : IHouseConfiguration
{
    public HouseConfiguration(int noOfDoors, int noOfWindows)
    {
        this.noOfDoors = noOfDoors;
        this.noOfWindows = noOfWindows;
    }
    public int noOfDoors
    {
        get { return noOfDoors; }
        set { noOfDoors = value; }
    }
    public int noOfWindows
    {
        get { return noOfWindows; }
        set { noOfWindows = value; }
    }
    public bool IsValid()
    {
        //do validate calculus and return value. For a true, i do not sure it is IHouseConfiguration's duty...
        return true;
    }
}
public class Contractor
{
    public House buildHouse(IHouseConfiguration houseConfiguration)
    {
        if (houseConfiguration.IsValid())
        {
            return new House(houseConfiguration);
        }
        return null;
    }
}
public class House
{
    private Window[] windows;
    public House(IHouseConfiguration houseConfig) //Now, all incapsulated in IHouseConfiguration
    {
        Window[] windows = new Window[houseConfig.noOfDoors];
        this.windows = windows;
    }
}

最新更新