建造者模式
什么是建造者模式
建造者模式是将一个复杂对象的构建与它的表示分里,是的同样的构建过程可以创建不同的表示。
简单来说,当我们需要一个复杂的对象,这个对象由许多组件组成,并且装配方式比较复杂时,就需要使用建造者模式来屏蔽这些装配细节,只需要关心最终的对象即可。
其类图如下:
为什么要用建造者模式
我们来想这么一个情况:现在有一个开发商,需要在一片地区上盖楼。
用代码模拟出来很简单吧。
首先我们需要明确盖房子的步骤,假设只有打地基、砌墙、盖房顶三步:
需要有一个房子类:
public class House {
private String type;
public House(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
现在开始建造:
public class Developer {
public static void main(String[] args) {
House house = new House("common");
System.out.println("给" + house.getType() + "打地基...");
System.out.println("给" + house.getType() + "砌墙...");
System.out.println("给" + house.getType() + "盖房顶...");
}
}
这样,我们就完成了一栋房子的建造,我们要接着建造别的房子,就需要重复上面的步骤。
但是,这也有很多问题:
- 如果建房子的三步反了怎么办?
- 作为开发商,现在是亲手去盖楼房,这似乎有些不合适。
- 如果不仅仅是建造一种房子怎么办,还要自己知晓每一种房子的构建方法吗?
现实中,开发商需要找施工队来进行建设,施工队对于楼房建造是很熟练的,这就成为了建造者模式:
- 开发商找到施工队
- 由施工队的负责人负责指挥管理
- 由工人进行建造
- 完成楼房建造工作
那么,用代码实现一下吧:
为了方便扩展,抽象出一个抽象房子作为房子的父类,不同类型的House都可以继承该AbstractHouse类来进行扩展:
public abstract class AbstractHouse {
protected String type;
protected int height;
protected int foundationDepth;
protected String roofType;
public AbstractHouse(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getFoundationDepth() {
return foundationDepth;
}
public void setFoundationDepth(int foundationDepth) {
this.foundationDepth = foundationDepth;
}
public String getRoofType() {
return roofType;
}
public void setRoofType(String roofType) {
this.roofType = roofType;
}
@Override
public String toString() {
return "AbstractHouse{" +
"type='" + type + '\'' +
", height=" + height +
", foundationDepth=" + foundationDepth +
", roofType='" + roofType + '\'' +
'}';
}
}
普通房子:
public class House extends AbstractHouse{
public House() {
super("Common");
}
}
别墅:
public class Villa extends AbstractHouse {
public Villa() {
super("Villa");
}
}
工人(具体建造者)类:
public abstract class Builder {
protected AbstractHouse house;
public abstract void lookBlueprint(); //查看蓝图,确定类型
public abstract void layFoundation(); //打地基
public abstract void buildWall(); //砌墙
public abstract void coverRoof(); //盖房顶
public abstract AbstractHouse handover(); //完成工作,交工
}
建造普通房子的工人:
public class CommonBuilder extends Builder {
@Override
public void lookBlueprint() {
house = new House();
}
@Override
public void layFoundation() {
house.setFoundationDepth(5);
}
@Override
public void buildWall() {
house.setHeight(20);
}
@Override
public void coverRoof() {
house.setRoofType("平顶");
}
@Override
public AbstractHouse handover() {
return this.house;
}
}
建造别墅的工人:
public class VillaBuilder extends Builder {
@Override
public void lookBlueprint() {
house = new Villa();
}
@Override
public void layFoundation() {
house.setFoundationDepth(5);
}
@Override
public void buildWall() {
house.setHeight(5);
}
@Override
public void coverRoof() {
house.setRoofType("尖顶");
}
@Override
public AbstractHouse handover() {
return this.house;
}
}
施工队负责人(指挥者)类:
public class Director {
public void construct(Builder builder){
builder.lookBlueprint();
builder.layFoundation();
builder.buildWall();
builder.coverRoof();
}
}
开发商:
public class Developer {
public static void main(String[] args) {
Director director = new Director();
Builder commonBuilder = new CommonBuilder();
Builder villaBuilder = new VillaBuilder();
director.construct(commonBuilder);
director.construct(villaBuilder);
System.out.println(commonBuilder.handover());
System.out.println(villaBuilder.handover());
}
}
当前类图
这样,我们就通过建造者模式实现了盖房的需求,开发商只需要找到指挥者,告诉他要盖什么类型的房子(指定哪队施工队来干)就可以符合标准地完成一套房子的建造,而无需关心盖楼的具体步骤。