您好,登錄后才能下訂單哦!
這篇文章主要講解了“設計模式系列之如何使用建造者模式”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“設計模式系列之如何使用建造者模式”吧!
1、概述
建造者模式是一種創建型設計模式, 使你能夠分步驟創建復雜對象。該模式允許你使用相同的創建代碼生成不同類型和形式的對象。
2、適用場景
1)避免重疊構造函數,例如:一個類有很多的屬性,這時候的構造方法需要傳遞很多的參數,為了避免這樣,會重新寫一個相對參數較少的構造方法,但是仍然需要對其他參數進行賦默認值。
2)當需要創建不同的產品類型,此處指比較接近的產品類型,則可以在頂層builder中包含大部分產品屬性的賦值方法。
3、實例
有以下場景,我們分別使用常規方式和建造者模式實現:
當前有一個汽車工廠,可以生產的汽車類型有ordinary,sport。 除了汽車之外,同樣可以生產汽車的操作手冊manual。 汽車有以下的屬性: 1、type 類型 2、seats 座位數 3、engine 引擎 4、GPS 導航 分別實現汽車和手冊的生產過程
不使用建造者模式
分別創建車car和手冊manual,以及其內部的屬性,當前例子中車和手冊是相同的屬性。
@Data public class Car { private CarType type; private int seats; private Engine engine; private GPS GPS; public Car(CarType type, int seats, Engine engine, com.cloud.bssp.designpatterns.builder.withouttdesign.entity.GPS GPS) { this.type = type; this.seats = seats; this.engine = engine; this.GPS = GPS; } public void detail() { System.out.println("this is " + type + " car"); System.out.println("the seats is :" + seats); System.out.println("the engine is :" + engine); System.out.println("this GPS is :" + GPS); } }
@Data public class Manual { private CarType type; private int seats; private Engine engine; private GPS GPS; public Manual(CarType type, int seats, Engine engine, com.cloud.bssp.designpatterns.builder.withouttdesign.entity.GPS GPS) { this.type = type; this.seats = seats; this.engine = engine; this.GPS = GPS; } public void detail() { System.out.println("this is " + type + " car"); System.out.println("the seats is :" + seats); System.out.println("the engine is :" + engine); System.out.println("this GPS is :" + GPS); } }
public enum CarType { SPORT,ORDINARY; }
/** * 汽車引擎 */ @Data public class Engine { /** * 排量 */ private final double volume; /** * 里程 */ private double mileage; public Engine(double volume, double mileage) { this.volume = volume; this.mileage = mileage; } }
@Data public class GPS { /** * 路線 */ private String route; public GPS(String route) { this.route = route; } }
測試類:
/** * 客戶端 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestDemo { @Test public void test() { //生產跑車 Car sportCar = new Car( CarType.SPORT, 2, new Engine(3.0, 0), new GPS("上海東方明珠塔到上海動物園") ); sportCar.detail(); System.out.println("----------------------------------------"); //生產普通汽車 Car ordinaryCar = new Car( CarType.ORDINARY, 4, new Engine(2.0, 0), new GPS("上海東方明珠塔到上海動物園") ); ordinaryCar.detail(); System.out.println("----------------------------------------"); //生產汽車操作手冊 Manual manual = new Manual( CarType.ORDINARY, 4, new Engine(2.0, 0), new GPS("上海東方明珠塔到上海動物園") ); manual.detail(); System.out.println("----------------------------------------"); } }
結果:
this is SPORT car the seats is :2 the engine is :Engine(volume=3.0, mileage=0.0) this GPS is :GPS(route=上海東方明珠塔到上海動物園) ---------------------------------------- this is ORDINARY car the seats is :4 the engine is :Engine(volume=2.0, mileage=0.0) this GPS is :GPS(route=上海東方明珠塔到上海動物園) ---------------------------------------- this is ORDINARY car the seats is :4 the engine is :Engine(volume=2.0, mileage=0.0) this GPS is :GPS(route=上海東方明珠塔到上海動物園) ----------------------------------------
使用建造者模式實現
使用建造者模式后,代碼要比上面的方法多了不少:
創建頂層Builder
public interface Builder { void setCarType(CarType carType); void setSeats(int seats); void setEngine(Engine engine); void setGPS(GPS gps); }
創建實體類,與上面是相同的,這里不重復了。
創建car的builder:
@Data public class CarBuilder implements Builder { private CarType carType; private int seats; private Engine engine; private GPS GPS; public Car getResult() { return new Car(carType, seats, engine, GPS); } }
創建汽車操作手冊builder:
@Data public class ManualBuilder implements Builder { private CarType carType; private int seats; private Engine engine; private GPS GPS; public Manual getResult() { return new Manual(carType, seats, engine, GPS); } }
創建一個builder管理器:
public class Director { public void constructSportsCar(Builder builder) { builder.setCarType(CarType.SPORT); builder.setSeats(2); builder.setEngine(new Engine(3.0, 0)); builder.setGPS(new GPS("上海東方明珠塔到上海動物園")); } public void constructOrdinaryCar(Builder builder) { builder.setCarType(CarType.ORDINARY); builder.setSeats(4); builder.setEngine(new Engine(2.0, 0)); builder.setGPS(new GPS("上海東方明珠塔到上海動物園")); } }
測試類:
@RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestDemo { @Test public void test() { Director director = new Director(); //生產跑車 CarBuilder carBuilder = new CarBuilder(); director.constructSportsCar(carBuilder); Car sportCar = carBuilder.getResult(); sportCar.detail(); System.out.println("-----------------------------------"); //生產普通汽車 director.constructOrdinaryCar(carBuilder); Car ordinaryCar = carBuilder.getResult(); ordinaryCar.detail(); System.out.println("-----------------------------------"); //生產汽車操作手冊 ManualBuilder manualBuilder = new ManualBuilder(); director.constructOrdinaryCar(manualBuilder); Manual manual = manualBuilder.getResult(); manual.detail(); System.out.println("-----------------------------------"); } }
結果:
this is SPORT car the seats is :2 the engine is :Engine(volume=3.0, mileage=0.0) this GPS is :GPS(route=上海東方明珠塔到上海動物園) ----------------------------------- this is ORDINARY car the seats is :4 the engine is :Engine(volume=2.0, mileage=0.0) this GPS is :GPS(route=上海東方明珠塔到上海動物園) ----------------------------------- this Manual ORDINARY car the Manual seats is :4 the Manual engine is :Engine(volume=2.0, mileage=0.0) this GManual PS is :GPS(route=上海東方明珠塔到上海動物園) -----------------------------------
4、分析
建造者模式基本有以下幾個角色:
如上面兩種方式的結果顯示,都可以實現生產汽車和汽車手冊。
結果沒什么差異。
在沒使用建造者的方式中:
生產汽車的參數是由客戶端自己指定的,并且需要傳很多的參數,實際工作中可能需要更多的參數,可能有部分參數是不需要的。
使用建造者模式
用戶不需要去具體指定多個參數了,對于客戶端更友好。
builder:將產品new()提出到builder中,提供產品所擁有的屬性設置方法,一類產品都可以使用這個builder進行產品創建。
director:作為builder的管理者,主要控制產品的屬性設置,在這個類中,具體指定除了可以生產的產品的構造,并且對屬性進行賦值,最終返回一個用戶需要的builder。
客戶端調用只需要創建需要的產品類型builder,通過管理者director對builder進行屬性設置,最終客戶端通過調用builder的方法獲取最終需要的產品。
極大程度減少并優化的客戶端的代碼,同時由管理者director限制了產品的種類。
從擴展層層面看:
未使用建造者:增加對應的產品類,客戶端直接new。
使用建造者模式:增加builder,并且在director增加可創建的產品的builder構造。
5、總結
最后總結下上面例子中使用抽象工廠方法的優缺點:
優點:
1)遵守單一原則。
2)不同產品,可復用相同的產品創建流程。
3)簡化客戶端調用方式。去除多參構造的方式。
4)分步驟創建對象。
缺點:
增加多個類,代碼復雜度增加。
感謝各位的閱讀,以上就是“設計模式系列之如何使用建造者模式”的內容了,經過本文的學習后,相信大家對設計模式系列之如何使用建造者模式這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。