建造者模式扩展 & 总结篇
再把定义说一遍:将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。
上一篇介绍完了建造者模式,但是还有一个疑问,就是定义中的表示,除了内部关联的对象不同,还可以是这个对象的行为,关于行为该怎么表现呢?可以结合模板方法模式实现行为的不同。
模板方法模式本身是不能按照任意的顺序调用方法的,通过与建造者模式的结合,可以实现这个需求
abstract class AbstractProduct{
private List<String> list;
protected abstract void method1();
protected abstract void method2();
protected abstract void method3();
public void setList(List<String> list) {
this.list = list;
}
public final void run() {
for(String str : this.list) {
if(str.equals("method1"))
method1();
else if(str.equals("method2"))
method2();
else if(str.equals("method3"))
method3();
}
}
}
class Product extends AbstractProduct {
@Override
protected void method1() {
System.out.println("call method1");
}
@Override
protected void method2() {
System.out.println("call method2");
}
@Override
protected void method3() {
System.out.println("call method3");
}
}
interface Builder {
void setList();//设置模板方法模式中的特定方法的执行顺序
AbstractProduct getProduct();
}
class ProductBuilder implements Builder {
AbstractProduct p = new Product();
@Override
public void setList() {
List<String> list = new ArrayList<>();
list.clear();
list.add("method1");
list.add("method2");
list.add("method3");
list.add("method1");
}
public AbstractProduct getProduct() {
return this.p;
}
}
class Director {
public AbstractProduct getProduct(Builder b) {
b.setList();
return b.getProduct();
}
}
public class Client {
public static void main(String[] args) {
Director d = new Director();
Builder b = new ProductBuilder();
AbstractProduct p = d.getProduct(b);
p.run();
}
}
创建一个一个新的Builder对象,在里面设置它的方法的执行顺序,虽然看起来它的构建过程没变,但是行为发生了变化。
总结
适用场景
- 相同的方法,不同的执行顺序,产生不同的结果。(就是刚才扩展过的结合模板方法模式)
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同。
- 产品类非常复杂,产品类中的调用顺序不同产生了不同的效能。
优点
- 封装性,啥也不用管,跟工厂一样,要某个产品,直接调用就可以了,只关心接口,不关心过程。
- 建造者独立,容易扩展。Builder可以由很多实现类,而不用关心具体的构建顺序。