我正在使用构建器模式构建JavaBean(仅限字段和getter / setter)。
为了这个例子,假设这是我们的bean:
public class Pizza {
private int size;
private boolean cheese;
private boolean pepperoni;
private boolean bacon;
private Pizza(Builder builder) {
size = builder.size;
cheese = builder.cheese;
pepperoni = builder.pepperoni;
bacon = builder.bacon;
}
public static class Builder {
//required
private final int size;
//optional
private boolean cheese = false;
private boolean pepperoni = false;
private boolean bacon = false;
public Builder(int size) {
this.size = size;
}
public Builder cheese(boolean value) {
cheese = value;
return this;
}
public Builder pepperoni(boolean value) {
pepperoni = value;
return this;
}
public Builder bacon(boolean value) {
bacon = value;
return this;
}
public Pizza build() {
return new Pizza(this);
}
}
}
取自here。
现在我一直在尝试确保Pizza
中的所有字段都是非空的,带有反射,迭代Pizza
的字段并检查它们是否为空,但它出现(我可能在这里错了)我的字段在检查发生之前没有设置。 Jon Skeet的This code是我改变以检查我的字段的非零性(而不是计数,我正在抛出异常)。
然后我尝试检查构建器的字段,但是在构建器中有额外的字段(例如,我有一个XMLParser字段,可能为null)。通过披萨字段对构建器字段进行子集不起作用,因为它们具有不同的“包路径”(?),例如, org.GiusepesPizzaria.pizza.size
vs org.GiusepesPizzaria.builder.size
有更好的方法来检查吗?在实现反射方法之前,我使用了这种构造:
if(builder.size ==null){
throw new BadPizzaException("Eh, what're ya doin'?"+
" Pizza Size was not set correctly");
}else{
size=builder.size;
}
但最终,如果你说要检查〜10个字段,啰嗦,杂乱应该是一个简单的类。
这就是我尝试过的。有更好的方法吗?
答案 0 :(得分:2)
确保设置所有变量的一个有趣模式是使用Step Builder Pattern,其中第一个setter只允许你设置第二个,第二个只允许第三个,依此类推。当你在最后一步时,你可以建立这个类,然后你就会知道所有方法都被调用了。
该帖子的简短摘录:
Panino solePanino = PaninoStepBuilder.newBuilder()
.paninoCalled("sole panino")
.breadType("baguette")
.fish("sole")
.addVegetable("tomato")
.addVegetable("lettece")
.noMoreVegetablesPlease()
.build();
你必须从panino的调用开始,然后用面包类型跟进。
答案 1 :(得分:0)
试试这个:
public class Pizza
{
private final boolean bacon;
private final boolean cheese;
private final boolean pepperoni;
private final int size;
private Pizza()
{
throw new UnsupportedOperationException();
}
Pizza(
final int theSize,
final boolean theCheese,
final boolean thePepperoni,
final boolean theBacon)
{
bacon = theBacon;
cheese = theCheese;
pepperoni = thePepperoni;
size = theSize;
}
}
// new file.
public class PizzaBuilder
{
private boolean bacon;
private boolean cheese;
private boolean pepperoni;
private int size;
public PizzaBuilder()
{
size = 9; // default size.
}
public void setHasBacon()
{
bacon = true;
}
public void setHasNoBacon()
{
bacon = false;
}
public void setHasCheese()
{
cheese = true;
}
public void setHasNoCheese()
{
cheese = false;
}
public void setHasPepperoni()
{
pepperoni = true;
}
public void setHasNoPepperoni()
{
pepperoni = false;
}
public void setSizeNineInch()
{
size = 9;
}
public void setSizeTwelveInch()
{
size = 12;
}
public Pizza buildPizza()
{
return new Pizza(size, cheese, pepperoni, bacon);
}
}
使用上面的构建器,构建器不可能生成无效的披萨。
假设:仅支持9英寸和12英寸的披萨。根据需要添加更多setSize。
构建器使用我称为NMSetters的内容。此样式设置器允许您设置值,但不公开所述值的实现。这似乎不是我的原创发明。