一、
问题:在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成。由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
这个描述和模板方法模式很相似,但是这个模式主要解决创建工作。
比如创建房子,步骤是一样的,但是每个步骤的具体实现时不一样的。
我们可以将对象的表示与创建部分相分离,使其可以用相同的创建步骤来描述不同的表示。
二、像当初写Android时,经常使用的方法那样。
问题:当一个类有很多参数需要配置,有些是必须的,有些是可选的。那么有几种做法:
做法一:将必须赋值的参数放入类的构造函数中,其他可选的参数提供setting/getting方法。
这样做的缺点是,当可选的参数很多时,实使用起来需要调用很多setting方法。那么有可能还没setting完,这个不完整的对象就被获得使用了。
做法二:重建很多构造函数,使用者根据需要配置的参数选择不同的构造函数。
这样做的缺点是,构造函数会特别多,是可选参数个数的组合。
做法三:构建器模式,将类A参数的配置(也就是对象的构建)提取成一个类Abuilder ,这个类Abuilder 一般是内部类。
1. 在这个内部类Abuilder 中写setting方法用来配置可选参数,并为所有的setting方法返回本对象a。
2. Abuilder 中有一个builder方法,就是调用A的构造方法,返回一个A的对象。
3. A的构造方法为私有方法,只能通过这个内部类调用,该方法有参数Abuilder ,在该构造方法中,将a的字段值完全赋值给A,并返回A对象。
4. A与Abuilder 的字段完全相同
5. Abuilder 的构造函数应该包含所有必选的参数。
6. Abuilder必须声明为public static class Abuilder{}因为使用的时候是通过A的类名调用Abuilder的构造函数的。
具体代码:
class A{
string name;
int age;
private A(Abuilder a){
this.name=a.name;
this.age=a.age;
}
//内部构建器类
public static class Abuilder{
string name;
int age;
public Abuilder(string name){}//必选参数
public settingAge(int age){//可选参数
this.age=age;
return this;
}
public A builder(){
return new A(this);
}
}
}
使用:
A a = A.Abuilder("张三").settingAge(20).builder();
Java设计模式系列 — 构造器模式 - 饭小胖 - 博客园
总结,这两种方法都是将构建部分提取成一个类,只是一个是一般类,类中固有原类的对象,通过这个对象来配置成员变量。一个是内部类,这个内部类有和原类一样的成员变量,在最后返回类时,将自己的变量值赋给原类。
另外:
如果一个方法是一个流程的单个步骤,对外部来说没什么意义,则不要将其声明为public。