Builder模式的缘起:假设创建游戏中的一个房屋House设施,该房屋的构建由几部分组成,且各个部分富于变化。如果使用最直观的设计方法,每一个房屋部分的变化,都将导致房屋构建的重新修正.....
动机(Motivation):在软件系统中,有时候面临一个"复杂对象"的创建工作,其通常由各个部分的子对象用一定算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合到一起的算法却相对稳定。
意图(Intent):将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 -------《设计模式》GOF
结构图:
角色及其职责
Product 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
Builder 抽象建造者:规范产品的组建,一般是由子类实现。
ConcreteBuilder 具体建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
Director 导演:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。
代码示例:
抽象建造者:Builder
package com.jin.model.builder;
public abstract class Builder {
public abstract void buildDoor();
public abstract void buildWall();
public abstract void buildWindows();
public abstract void buildFloor();
public abstract void buildHouseCeiling();
public abstract House getHouse();
}
Director类:组合到一起的算法(相对稳定)导演类就是起到封装的作用,避免高层模块深入到建造者内部的实现类。当然,在建造者模式比较庞大时,导演类可以有多个。
package com.jin.model.builder;
public class Director {
public void construct(Builder builder) {
builder.buildWall();
builder.buildHouseCeiling();
builder.buildDoor();
builder.buildWindows();
builder.buildFloor();
}
}
产品:House
package com.jin.model.builder;
public class House {
}
ChineseBuilder类
package com.jin.model.builder;
public class ChineseBuilder extends Builder {
private House chineseHouse = new House();
public void buildDoor() {
System.out.println("this Door 's style of Chinese");
}
public void buildWall() {
System.out.println("this Wall 's style of Chinese");
}
public void buildWindows() {
System.out.println("this Windows 's style of Chinese");
}
public void buildFloor() {
System.out.println("this Floor 's style of Chinese");
}
public void buildHouseCeiling() {
System.out.println("this Ceiling 's style of Chinese");
}
public House getHouse() {
return chineseHouse;
}
}
RomanBuilder类
package com.jin.model.builder;
public class RomanBuilder extends Builder {
private House chineseHouse = new House();
public void buildDoor() {
System.out.println("this Door 's style of Roman");
}
public void buildWall() {
System.out.println("this Wall 's style of Roman");
}
public void buildWindows() {
System.out.println("this Windows 's style of Roman");
}
public void buildFloor() {
System.out.println("this Floor 's style of Roman");
}
public void buildHouseCeiling() {
System.out.println("this Ceiling 's style of Roman");
}
public House getHouse() {
return chineseHouse;
}
}
这个复杂对象的两个部分经常面临着剧烈的变化。
客户端:Client
package com.jin.model.builder;
public class Client {
public static void main(String[] args) {
Director director = new Director();
Builder builder = new ChineseBuilder();
director.construct(builder);
House house = builder.getHouse();
}
}
使用场景
1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2. 当构造过程必须允许被构造的对象有不同的表示时。
几个要点:
Builder模式 主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的乘法,而复杂对象的各个部分则经常变化。
Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
Abstract Factory模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。Builder模式通常和Composite模式组合使用。