简介
为什么要使用建造者模式
在软件开发中,有时会面临一个创建复杂对象的问题。这个复杂对象的成员很复杂,创建过程也很复杂。这时,就需要使用建造者模式将这个复杂对象的构建分离到一个称谓建造者的对象里。即由这个建造者来创建并返回一个完整的复杂对象。
什么是建造者模式
建造者模式(Builder Pattern,BP):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
类型
对象创建型模式
遵守的原则
符合“开闭原则”。指挥者类针对抽象建造者类编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便。
角色
- Product:产品角色,被构建的复杂对象。
- Builder:抽象建造者。可以是抽象类或者接口。为创建Product对象的各个part提供抽象方法。 在其中一般声明两类方法:1、buildPartX(),用于创建Product对象的某个part;2、getResult(),装配part,用于返回一个完整的Product对象。
- ConcreteBuilder:具体建造者,实现了或继承了Builder的类。实现buildPartX(),用于创建Product对象的某个part;实现getResult(),装配part,用于返回一个完整的Product对象。
- Director:指挥者,负责复杂对象各个part的建造次序。与Builder之间存在关联关系,调用Builder方法完成复杂对象的建造。一般客户端只需要与Director交互。
UML类图
简化
如果只有一个具体建造者,那么抽象建造者和指挥者都可以省略。
实现
- 创建Product类
- 创建Builder接口
- 创建两个构建方式:ConcreteBuilder类和ConcreteBuilder2
- 创建Director类
Product.java
class Product {
private String partA;
private String partB;
private String partC;
//省略Getter和Setter方法、toString()方法
}
Builder.java
public interface Builder {
public void buildPartA();
public void buildPartB();
public void buildPartC();
public Product getResult();
}
ConcreteBuilder.java
public class ConcreteBuilder implements Builder{
Product product = new Product();
@Override
public void buildPartA() {
product.setPartA("A");
}
@Override
public void buildPartB() {
product.setPartB("B");
}
@Override
public void buildPartC() {
product.setPartC("C");
}
@Override
public Product getResult() {
return product;
}
}
ConcreteBuilder2.java
public class ConcreteBuilder2 implements Builder{
Product product = new Product();
@Override
public void buildPartA() {
product.setPartA("aa");
}
@Override
public void buildPartB() {
product.setPartB("bb");
}
@Override
public void buildPartC() {
product.setPartC("cc");
}
@Override
public Product getResult() {
return product;
}
}
Director.java
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void setBuilder(Builder builder) {
this.builder = builder;
}
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
测试类
BuilderPatternTest.java
public class BuilderPatternTest {
public static void main(String[] args) {
ConcreteBuilder concreteBuilder= new ConcreteBuilder();
Director director = new Director(concreteBuilder);
Product product = director.construct();
System.out.println(product.toString());
ConcreteBuilder2 concreteBuilder2 = new ConcreteBuilder2();
director = new Director(concreteBuilder2);
product = director.construct();
System.out.println(product.toString());
}
}
测试结果
Product [partA=A, partB=B, partC=C]
Product [partA=aa, partB=bb, partC=cc]
在客户端代码中,无须关心产品对象的具体组装过程,只需确定具体建造者的类型即可,建造者模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。
优缺点
优点
- 低耦合。在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦。每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
- 符合“开闭原则”。指挥者类针对抽象建造者类编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便。
缺点
使用范围有限。如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
适用环境
产品结构复杂,创建对象过程复杂
使用场景
游戏角色。
问题
建造者模式和抽象工厂模式的比较
返回的产品个数不同。建造者模式只能返回一个复杂产品;而抽象工厂模式可以返回很多产品。
在软件开发中,你在哪里用到了建造者模式?
面试的时候经常被问到,好好想想吧^^
本文已收录于专栏:24种设计模式