定义
建造者模式(Builder)是一种对象构建模式,用来封装一个产品的构造过程,并允许按步骤构造产品。
建造者模式又叫生成器模式,建造者模式属于创建型模式。
要点
- 经常被用来创建组合结构
- 将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象
- 一步一步创建一个复杂的对象,客户只需要通过指定复杂对象的类型和内容就可以构建它们而不需要知道产品的构建细节
- Product(产品): 一个具体的产品对象。
- Builder(抽象建造者): 创建产品对象各个部件构造规范。
- ConcreteBuilder(具体建造者): 实现接口,执行构建和装配各个部件。
场景
建房子的过程分为打桩、砌墙、封顶三个大步骤。不管是普通房子也好,别墅也好都需要经历这些过程,需要设计一个有弹性的代码工程来代表建房子的规划以及所有的变化,当然也需要遵循一系列潜在的复杂建造流程细节。
实现
房子
/**
* 产品: 房子
*/
public class House {
/**
* 地基
*/
private String base;
/**
* 墙面
*/
private String wall;
/**
* 屋顶
*/
private String roof;
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
@Override
public String toString() {
return "House{" +
"base='" + base + '\'' +
", wall='" + wall + '\'' +
", roof='" + roof + '\'' +
'}';
}
}
房子建造者(抽象)
/**
* 房屋建造者(抽象)
*/
public abstract class AbstractHouseBuilder {
/**
* 房子对象
*/
protected House house;
/**
* 建造地基
*/
protected abstract void buildBase();
/**
* 建造墙面
*/
protected abstract void buildWall();
/**
* 建造房顶
*/
protected abstract void buildRoof();
/**
* 建房子的流程
*/
public House buildHouse() {
house = new House();
buildBase();
buildWall();
buildRoof();
return house;
}
}
别墅建造者
/**
* 别墅建造者
*/
public class VillaBuilder extends AbstractHouseBuilder {
@Override
protected void buildBase() {
System.out.println("别墅的地基打30米");
house.setBase("30米深");
}
@Override
protected void buildWall() {
System.out.println("别墅的墙砌25公分宽");
house.setWall("25公分宽");
}
@Override
protected void buildRoof() {
System.out.println("别墅的房顶使用定制琉璃瓦");
house.setRoof("定制琉璃瓦");
}
}
平房建造者
/**
* 平房建造者
*/
public class CottageBuilder extends AbstractHouseBuilder {
@Override
protected void buildBase() {
System.out.println("平房的地基打15米");
house.setBase("15米深");
}
@Override
protected void buildWall() {
System.out.println("平房的墙砌20公分宽");
house.setWall("20公分宽");
}
@Override
protected void buildRoof() {
System.out.println("平房的房顶使用水泥");
house.setRoof("水泥");
}
}
源代码
总结
-
建造者模式将一个复杂对象的创建过程封装起来
建造者模式所创建的产品一般具有较多的共同点,其组成部分相似。 -
允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)
可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰, 也更方便使用程序来控制创建过程。 -
向客户隐藏产品的内部实现
客户不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。 -
产品的实现可以被替换,因为客户只看到一个抽象的接口。
每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象。
注意:
如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,因此在这种情况下,要考虑是否选择建造者模式。
应用:Java中的 StringBuilder 类就使用了建造者模式。
抽象工厂模式 VS 建造者模式
抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。
而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。