在使用构建器模式时,我应该如何保留OOP的封装原则?我的意思是,构建器应该在对象和使用它的代码之间提供抽象层,这样它就可以被逐部分地构造,这需要为我们通常会传递到构造器中的对象的每个参数创建setter。这在某些情况下可能是不希望的,因为我不希望客户机能够修改值,我必须通过构建器。下面举例说明我的意思:
public class Cat
{
private string _race;
private string _name;
public Cat()
{
_race = "common";
_name = string.Empty;
}
public void setRace(string race) { _race = race; }
public void setName(string name) { _name = name; }
}
public class CatBuilder
{
private Cat _objectUnderConstruction;
public CatBuilder() { _objectUnderConstruction = new Cat(); }
public CatBuilder WithName(string name)
{
_objectUnderConstruction.setName(name);
return this;
}
public CatBuilder OfRace(string race)
{
_objectUnderConstruction.setRace(race);
return this;
}
}
这不是生产代码,我现在写它的时候考虑的是表示形式,所以不要对它的构造方式发火。
在上面的例子中,需要设置Cat's race,因为我们需要该信息来填充对象,所以我们需要传递给它。同时,我不希望任何人改变我的猫在它的一生中的种族(例如,它会改变从埃及到英国在中间处理),所以通常我会摆脱访问器方法,但我需要为构建器。这样,数据的封装就会受到损害(因为直接的get和set根本不能封装任何东西),我想避免它。
这个例子很简单,我可以在构造函数中传递参数,但是想象一下更大的类,那里有很多这样的字段,在这种情况下该怎么办?我应该在内部传递一些配置对象(这几乎像builder,但更简单,因此builder毫无意义)还是将builder本身传递给构造函数(这很奇怪,但我知道什么)?
我该怎么做?
如果构建器与类紧密耦合,则可以使
public class Cat
{
private string _race;
private string _name;
public Cat()
{
_race = "common";
_name = string.Empty;
}
private void setRace(string race) { _race = race; }
private void setName(string name) { _name = name; }
public class Builder
{
private Cat _objectUnderConstruction;
public CatBuilder() { _objectUnderConstruction = new Cat(); }
public CatBuilder WithName(string name)
{
_objectUnderConstruction.setName(name);
return this;
}
public CatBuilder OfRace(string race)
{
_objectUnderConstruction.setRace(race);
return this;
}
}
}
这样,您就可以在