因此,当我编写自己的项目时,初始化对象出现了问题。我的班级有很多需要启动的属性,但并不总是所有属性都是。当我提出这个想法时(但我不确定它是否在任何地方使用过之前):
public class MyClass {
public static final int DEFAULT1 = 1;
public static final int DEFAULT2 = 2;
public static final int DEFAULT3 = 3;
private int attr1;
private int attr2;
private int attr3;
private MyClass(){
attr1 = DEFAULT1;
attr2 = DEFAULT2;
attr3 = DEFAULT3;
}
public static MyClass create(){
return new MyClass();
}
public MyClass setAttr1(int attr1){
this.attr1 = attr1;
return this;
}
public MyClass setAttr2(int attr2){
this.attr2 = attr2;
return this;
}
public MyClass setAttr3(int attr3){
this.attr3 = attr3;
return this;
}
}
当我创建一个新的MyClass
实例时,我会这样做:
MyClass obj = MyClass.create().setAttr1(3).setAttr3(1);
它对我有用(因为我测试了它,但我还没决定在我的项目中使用它)。我的问题是,这是合法的吗?它会创建任何类型的内存/执行问题吗?
答案 0 :(得分:7)
您的用例是Builder
设计模式的完美示例。详细了解here和oracle doc about builder。另请阅读为什么Builder
模式优于Java图例Joshua
的其他创建模式,这在他的书中讨论,java的最佳实践
here
使用Builder
设计模式转换后的课程如下所示。请注意,我假设attr1
是可选的,attr2
和attr3
是强制性的。
class MyClass {
public static final int DEFAULT1 = 1;
public static final int DEFAULT2 = 2;
public static final int DEFAULT3 = 3;
// assume attr1 is optional
private int attr1;
// assume attr2,3 is mandatory
private int attr2;
private int attr3;
public MyClass(MyClassBuilder myClassBuilder) {
this.attr1 = myClassBuilder.attr1;
this.attr2 = myClassBuilder.attr2;
this.attr3 = myClassBuilder.attr3;
}
//Builder Class
public static class MyClassBuilder {
// required parameters
private int attr2;
private int attr3;
// optional parameters
private int attr1;
public MyClassBuilder(int attr2, int attr3){
this.attr2 = attr2;
this.attr3 = attr3;
}
public MyClassBuilder setAttr1(int attr1) {
this.attr1 = attr1;
return this;
}
public MyClass build(){
return new MyClass(this);
}
}
}
现在使用下面的代码后,你可以创建对象(有/没有)可选参数。
public class MyClassTest {
public static void main(String[] args) {
MyClass myClass = new MyClass.MyClassBuilder(10,20).build();
// without optional param
System.out.println("without optional param");
System.out.println("attr1 "+ myClass.getAttr1());
System.out.println("attr2 "+ myClass.getAttr2());
System.out.println("attr3 "+ myClass.getAttr3());
// with optional param
System.out.println("with optional param");
MyClass myClassWithAllParam = new MyClass.MyClassBuilder(10,20).setAttr1(5).build();
System.out.println("attr1 "+ myClassWithAllParam.getAttr1());
System.out.println("attr2 "+ myClassWithAllParam.getAttr2());
System.out.println("attr3 "+ myClassWithAllParam.getAttr3());
}
}
输出如下: -
without optional param
attr1 0
attr2 10
attr3 20
with optional param
attr1 5
attr2 10
attr3 20
答案 1 :(得分:2)
另一个名字是Fluent Interface。
您只需使用with
代替set
作为方法名称。 set
命名是为JavaBeans约定保留的。