建造者模式
1、建造者模式的定义
-
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
-
将客户端与包含多个部件的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可
-
关注如何逐步创建一个复杂的对象,不同的建造者定义了不同的创建过程
2、建造者模式的结构
•Builder(抽象建造者)
•ConcreteBuilder(具体建造者)
•Product(产品)
•Director(指挥者)
3、建造者模式的实现
-
复杂对象类代码:
public class Product { private String partA; //定义部件,部件可以是任意类型,包括值类型和引用类型 private String partB; private String partC; //partA的Getter方法和Setter方法省略 //partB的Getter方法和Setter方法省略 //partC的Getter方法和Setter方法省略 }
-
抽象建造者类代码:
public abstract class Builder { //创建产品对象 protected Product product=new Product(); public abstract void buildPartA(); public abstract void buildPartB(); public abstract void buildPartC(); //返回产品对象 public Product getResult() { return product; } } public class Director { private Builder builder; public Director(Builder builder) { this.builder=builder; } public void setBuilder(Builder builder) { this.builder=builer; } //产品构建与组装方法 public Product construct() { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); return builder.getResult(); } }
-
客户类代码片段:
Builder builder = new ConcreteBuilder1(); //可通过配置文件实现 Director director = new Director(builder); Product product = director.construct();
-
结果及分析
-
如果需要更换具体角色建造者,只需要修改配置文件
-
当需要增加新的具体角色建造者时,只需将新增具体角色建造者作为抽象角色建造者的子类,然后修改配置文件即可,原有代码无须修改,完全符合开闭原则
-
钩子方法的引入
public class ActorController { public Actor construct(ActorBuilder ab) { Actor actor; ab.buildType(); ab.buildSex(); ab.buildFace(); ab.buildCostume(); //通过钩子方法来控制产品的构建 if(!ab.isBareheaded()) { ab.buildHairstyle(); } actor=ab.createActor(); return actor; } }
模式优点
-
客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
-
一个具体建造者都相对独立,与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,扩展方便,符合开闭原则
-
可以更加精细地控制产品的创建过程
模式适用环境
-
需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员变量
-
需要生成的产品对象的属性相互依赖,需要指定其生成顺序
-
对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中
-
隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品