应用场景
我觉得建造者模式的应用场景拿来与工厂模式做比较是最好的,工厂模式侧重的是解决创建实例对象产生的冗余问题,侧重的是创建对象结果,而我们的建造者模式侧重的是创建过程,下面我们引出一个问题描述:
传统的解决方案:
一个抽象的房子类封装各种方法,构造CommonHouse继承实现构造CommonHouse的操作,构造HighBuilding同理。
问题所在:
耦合性过于强,我们将房子和建房的操作死死的锁在了一起。
解决方案:将产品和产品的建造过程进行解耦!
建造者模式
建造者的四个角色:
解决上述问题:
这样我们就将产品和产品的创造过程进行了解耦。
public abstract class HouseBuilder {
protected House house = new House();
//将建造的流程写好, 抽象的方法
public abstract void buildBasic();
public abstract void buildWalls();
public abstract void roofed();
//建造房子好, 将产品(房子) 返回
public House buildHouse() {
return house;
}
}
public class HighBuilding extends HouseBuilder {
@Override
public void buildBasic() {
// TODO Auto-generated method stub
System.out.println(" 高楼的打地基100米 ");
}
@Override
public void buildWalls() {
// TODO Auto-generated method stub
System.out.println(" 高楼的砌墙20cm ");
}
@Override
public void roofed() {
// TODO Auto-generated method stub
System.out.println(" 高楼的透明屋顶 ");
}
}
//指挥者,这里去指定制作流程,返回产品
public class HouseDirector {
HouseBuilder houseBuilder = null;
//构造器传入 houseBuilder
public HouseDirector(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//通过setter 传入 houseBuilder
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//如何处理建造房子的流程,交给指挥者
public House constructHouse() {
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.roofed();
return houseBuilder.buildHouse();
}
}
public class Client {
public static void main(String[] args) {
//盖普通房子
CommonHouse commonHouse = new CommonHouse();
//准备创建房子的指挥者
HouseDirector houseDirector = new HouseDirector(commonHouse);
//完成盖房子,返回产品(普通房子)
House house = houseDirector.constructHouse();
//System.out.println("输出流程");
System.out.println("--------------------------");
//盖高楼
HighBuilding highBuilding = new HighBuilding();
//重置建造者
houseDirector.setHouseBuilder(highBuilding);
//完成盖房子,返回产品(高楼)
houseDirector.constructHouse();
}
}
我在继续描述一下
如果是传统的方式抽象类:
public abstract class AbstractHouse {
//打地基
public abstract void buildBasic();
//砌墙
public abstract void buildWalls();
//封顶
public abstract void roofed();
public void build() {
buildBasic();
buildWalls();
roofed();
}
}
最明显的缺点就是这个build写死了,如果我们需要更改build要怎么办?难道去修改代码,那明显不符合我们设计模式的原则!
这时候我们的director的好处就体现出来了!我可以再搞个director,在另一个director中去我们去修改build就行,此时我们客户端只需叫另一个director去执行就好了,这就是解耦的好处!