建造者模式(Builder Pattern)是創建型型模式(Creational Pattern)的一種,與工廠方法、抽象工廠等創建型模式不同,建造者模式需要關注一些創建的細節,它將產品的內部表象和產品的生產過程分割開來,從而使得一個創建的過程可以創建出具有不同表象的產品對象。
建造者模式的英文原話是:Sepatate the construction of a complex object from its representation so that the same construction process can create different representation。
意思是,講一個複雜對象的構建和它的表示分離,使得同樣的構建過程可以創建出不同表象的表示。
建造者模式的UML如下:
共涉及到4個角色:
產品角色(Product):該角色是建造中的複雜對象。一個系統中可以有多個產品類,並且產品類之間可以有不同的接口實現,完全可以是不相關聯的。
抽象建造者(Builder):用於規範產品的各個部分組成,並進行抽象,一般獨立於應用程序的邏輯。
具體建造者角色(ConcreteBuilder):該角色實現抽象建造者中定義的所有方法,並返回一個建造好的產品實例。
導演類角色(Director):該角色負責安排已有模塊的順序,然後告訴Builder開始建造。
建造者模式的實例
我們希望創建一個建造過程來生產計算機,計算機是一個複雜的對象,由CPU、主板、硬盤、顯示器等構成,各個計算機中都存在着一些共性,但也存在着型號上的差異,導致具體的性能、外觀表現不一。
計算機分爲PC機和Server機,它們都有CPU、硬盤、操作系統,但一般Server機是不配顯示器的。
於是,產品角色Product:
Computer
public abstract class Computer {
private String type; //型號
private String cpu; //CPU
private String hardDisk; //硬盤
private String os; //操作系統
//Setter & Getter Methods
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getHardDisk() {
return hardDisk;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
}
兩個具體的產品角色
Server
public class DELL_R720 extends Computer {
public DELL_R720() {
this.setType("DELL R720 SERVER");
}
@Override
public String toString() {
String str = "型號: "+this.getType();
str += "\ncpu: "+this.getCpu();
str += "\n硬盤: "+this.getHardDisk();
str += "\n操作系統: "+this.getOs();
return str;
}
}
PC
public class ThinkPad extends Computer {
private String monitor; //顯示器
public ThinkPad() {
this.setType("ThinkPad PC");
}
public String getMonitor() {
return monitor;
}
public void setMonitor(String monitor) {
this.monitor = monitor;
}
@Override
public String toString() {
String str = "型號: "+this.getType();
str += "\ncpu: "+this.getCpu();
str += "\n硬盤: "+this.getHardDisk();
str += "\n操作系統: "+this.getOs();
str += "\n顯示器: " + this.getMonitor();
return str;
}
}
抽象建造者角色Builder
public interface ComputerBuilder {
public void buildCPU(); //建造CPU
public void buildHardDisk(); //建造硬盤
public void buildOS(); //建造操作系統
public void buildMonitor(); //建造顯示器
public Computer getComputer(); //獲取計算機實例
}
具體建造者角色ConcreteBuilder,實現了抽象建造者角色接口,與具體表現類對應,這裏有兩個具體的建造者
public class PCBuilder implements ComputerBuilder {
private ThinkPad pc = new ThinkPad();
@Override
public void buildCPU() {
pc.setCpu("i5-4750");
}
@Override
public void buildHardDisk() {
pc.setHardDisk("500G-720");
}
@Override
public void buildMonitor() {
pc.setMonitor("14s-LCD");
}
@Override
public void buildOS() {
pc.setOs("Windows 7");
}
@Override
public Computer getComputer() {
return pc;
}
}
public class ServerBuilder implements ComputerBuilder {
private DELL_R720 server = new DELL_R720();
@Override
public void buildCPU() {
// TODO Auto-generated method stub
server.setCpu("i7-201");
}
@Override
public void buildHardDisk() {
// TODO Auto-generated method stub
server.setHardDisk("3T-8000");
}
@Override
public void buildMonitor() {
//無顯示器
}
@Override
public void buildOS() {
// TODO Auto-generated method stub
server.setOs("Linux RedHat");
}
@Override
public Computer getComputer() {
return server;
}
}
導演角色Director
public class Director {
ComputerBuilder builder;
public ThinkPad productPC() {
builder = new PCBuilder();
builder.buildCPU();
builder.buildHardDisk();
builder.buildMonitor();
builder.buildOS();
return (ThinkPad)builder.getComputer();
}
public DELL_R720 productServer() {
builder = new ServerBuilder();
builder.buildCPU();
builder.buildHardDisk();
builder.buildOS();
return (DELL_R720)builder.getComputer();
}
}
至此,一個建造計算機的建造者模式就完成了
客戶端測試類:
public class Test {
public static void main(String[] args) {
Director director = new Director();
Computer pc = director.productPC();
System.out.println(pc);
System.out.println("------------------------");
Computer server = director.productServer();
System.out.println(server);
}
}
建造者模式的一些優點:
- 封裝性,使用建造者模式可以是客戶端不必知道產品的內部組成細節。
- 建造者獨立 ,容易擴展。
- 便於控制細節風險,由於具體的建造者是獨立的,因此可以對建造過程逐步細化,而不對其他的模塊產生任何的影響。
使用建造者模式的場景:
- 相同的方法,不同的執行順序,產生不同的結果,可以採用建造者模式。
- 多個不見或者零件,都可以裝配到一個對象上去,但是產生的結果又不相同,可以使用建造者模式。
- 產品類非常複雜,或者產品類中的不同的方法調用順序產生不通過的功效可以使用建造者模式。