建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個複雜的對象。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。java
一個 Builder 類會一步一步構造最終的對象。該 Builder 類是獨立於其餘對象的。算法
意圖:將一個複雜的構建與其表示相分離,使得一樣的構建過程能夠建立不一樣的表示。shell
主要解決:主要解決在軟件系統中,有時候面臨着"一個複雜對象"的建立工做,其一般由各個部分的子對象用必定的算法構成;因爲需求的變化,這個複雜對象的各個部分常常面臨着劇烈的變化,可是將它們組合在一塊兒的算法卻相對穩定。設計模式
什麼時候使用:==一些基本部件不會變,而其組合常常變化的時候。==ide
如何解決:將變與不變分離開。ui
優勢:this
缺點: 設計
1. 產品必須有共同點,範圍有限制。 code
2. 如內部變化複雜,會有不少的建造類。對象
使用場景: 一、須要生成的對象具備複雜的內部結構。 二、須要生成的對象內部屬性自己相互依賴。
注意事項:與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。而工廠更專一於零件的製造過程。
如今須要構建不少車輛,車的組成有車輪、外殼、發動機、方向盤等,每一個組件有不一樣品牌,最後須要根據客戶需求定製不一樣的車。(車的整體組成是同樣的,組成部件變化)
/** * @author objcfeng * @description 車的實體類 * @date 2020/11/2 */ public class Car { //車輪 private String wheel; //外殼 private String shell; //發動機 private String engine; //方向盤 private String steeringWheel; @Override public String toString() { return "Car{" + "wheel='" + wheel + '\'' + ", Shell='" + shell + '\'' + ", engine='" + engine + '\'' + ", steeringWheel='" + steeringWheel + '\'' + '}'; } public String getWheel() { return wheel; } public void setWheel(String wheel) { this.wheel = wheel; } public String getShell() { return shell; } public void setShell(String shell) { this.shell = shell; } public String getEngine() { return engine; } public void setEngine(String engine) { this.engine = engine; } public String getSteeringWheel() { return steeringWheel; } public void setSteeringWheel(String steeringWheel) { this.steeringWheel = steeringWheel; } }
//車的建造者 public abstract class CarBuilder { //造車輪的方法,由於實際上車輪多是一個複雜對象 public abstract void buildWheel(); //造外殼的方法 public abstract void buildShell(); //造引擎的方法 public abstract void buildEngine(); //造方向盤的方法 public abstract void buildSteeringWheel(); public abstract Car getCar(); }
建造者實現類,多個品牌組裝不一樣的組件
/** * @author objcfeng * @description 奔馳建造者 * @date 2020/11/2 */ public class BenzBuilder extends CarBuilder { private Car car=new Car(); @Override public void buildWheel() { car.setWheel("上好的車輪"); } @Override public void buildShell() { car.setShell("奔馳外殼"); } @Override public void buildEngine() { car.setEngine("奔馳產發動機"); } @Override public void buildSteeringWheel() { car.setSteeringWheel("有奔馳標識的方向盤"); } @Override public Car getCar() { return car; } }
/** * @author objcfeng * @description 寶馬建造者 * @date 2020/11/2 */ public class BmwBuilder extends CarBuilder { private Car car=new Car(); @Override public void buildWheel() { car.setWheel("上好的車輪"); } @Override public void buildShell() { car.setShell("寶馬外殼"); } @Override public void buildEngine() { car.setEngine("寶馬產發動機"); } @Override public void buildSteeringWheel() { car.setSteeringWheel("有寶馬標識的方向盤"); } @Override public Car getCar() { return car; } }
指揮者
/** * @author objcfeng * @description 指揮者,指導具體構建者如何構建產品,控制調用前後次序,並向調用者返回完整的產品類 * @date 2020/11/2 */ public class CarDirector { private CarBuilder builder; public CarDirector(CarBuilder builder) { this.builder = builder; } public Car build(){ builder.buildEngine(); builder.buildShell(); builder.buildSteeringWheel(); builder.buildWheel(); return builder.getCar(); } }
使用:
public class Main { public static void main(String[] args) { CarBuilder builder1=new BmwBuilder(); CarBuilder builder2=new BenzBuilder(); CarDirector carDirector = new CarDirector(builder1); Car car = carDirector.build(); System.out.println(car); } }
輸出
Car{wheel='上好的車輪', Shell='寶馬外殼', engine='寶馬產發動機', steeringWheel='有寶馬標識的方向盤'}
咱們發現,在CarBuilder的實現類中,老是有個重寫的getCar方法返回建立好的Car對象,而且CarBuilder的子類老是須要構建一個新的car對象。由於一個car對象只會被一個CarBuilder建立,所以,能夠將car對象提高到CarBuilder抽象類中建立。以下,
//建造者 public abstract class CarBuilder { //新增建立一個新的car對象 protected Car car = new Car(); //其餘方法不變 public abstract void buildWheel(); public abstract void buildShell(); public abstract void buildEngine(); public abstract void buildSteeringWheel(); //修改返回car對象方法 public Car getCar(){ return this.car; }; }
實現類
/** * @author objcfeng * @description 寶馬建造者 * @date 2020/11/2 */ public class BmwBuilder extends CarBuilder { //注意每一個給car對象構建組成部分的方法調用的是父類的car對象 @Override public void buildWheel() { super.car.setWheel("上好的車輪"); } @Override public void buildShell() { super.car.setShell("寶馬外殼"); } @Override public void buildEngine() { super.car.setEngine("寶馬產發動機"); } @Override public void buildSteeringWheel() { super.car.setSteeringWheel("有寶馬標識的方向盤"); } //子類不須要實現getCar方法 // @Override // public Car getCar() { // return car; // } }
其餘無需改變。