成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

建造者模式——不止提高代碼檔次

開發(fā) 前端
建造者模式是一種創(chuàng)建型設(shè)計(jì)模式, 使你能夠分步驟創(chuàng)建復(fù)雜對象。它允許用戶只通過指定復(fù)雜對象的類型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)。

[[405080]]

本文轉(zhuǎn)載自微信公眾號(hào)「JavaKeeper」,作者海星。轉(zhuǎn)載本文請聯(lián)系JavaKeeper公眾號(hào)。

簡介

Builder Pattern,中文翻譯為建造者模式或者構(gòu)建者模式,也有人叫它生成器模式。

建造者模式是一種創(chuàng)建型設(shè)計(jì)模式, 使你能夠分步驟創(chuàng)建復(fù)雜對象。它允許用戶只通過指定復(fù)雜對象的類型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)。

定義:將一個(gè)復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

hello world

程序員麼,先上個(gè) hello world 熱熱身

  1. public class User { 
  2.  
  3.     private Long id; 
  4.     private String name
  5.     private Integer age;  //可選 
  6.     private String desc; //可選 
  7.  
  8.     private User(Builder builder) { 
  9.         this.id = builder.id; 
  10.         this.name = builder.name
  11.         this.age = builder.age; 
  12.         this.desc = builder.desc
  13.     } 
  14.  
  15.     public static Builder newBuilder(Long id, String name) { 
  16.         return new Builder(id, name); 
  17.     } 
  18.  
  19.     public Long getId() {return id;} 
  20.     public String getName() {return name;} 
  21.     public Integer getAge() {return age;} 
  22.     public String getDesc() {return desc;} 
  23.  
  24.     @Override 
  25.     public String toString() { 
  26.         return "Builder{" + 
  27.                 "id=" + id + 
  28.                 ", name='" + name + '\'' + 
  29.                 ", age=" + age + 
  30.                 ", desc='" + desc + '\'' + 
  31.                 '}'
  32.     } 
  33.  
  34.     public static class Builder { 
  35.         private Long id; 
  36.         private String name
  37.         private Integer age; 
  38.         private String desc
  39.  
  40.         private Builder(Long id, String name) { 
  41.             Assert.assertNotNull("標(biāo)識(shí)不能為空",id); 
  42.             Assert.assertNotNull("名稱不能為空",name); 
  43.             this.id = id; 
  44.             this.name = name
  45.         } 
  46.         public Builder age(Integer age) { 
  47.             this.age = age; 
  48.             return this; 
  49.         } 
  50.         public Builder desc(String desc) { 
  51.             this.desc = desc
  52.             return this; 
  53.         } 
  54.         public User build() { 
  55.             return new User(this); 
  56.         } 
  57.  
  58.     } 
  59.  
  60.     public static void main(String[] args) { 
  61.         User user = User.newBuilder(1L, "starfish").age(22).desc("test").build(); 
  62.         System.out.println(user.toString()); 
  63.     } 

這樣的代碼有什么優(yōu)缺點(diǎn)呢?

主要優(yōu)點(diǎn):

  1. 明確了必填參數(shù)和可選參數(shù),在構(gòu)造方法中進(jìn)行驗(yàn)證;
  2. 可以定義為不可變類,初始化后屬性字段值不可變更;
  3. 賦值代碼可讀性較好,明確知道哪個(gè)屬性字段對應(yīng)哪個(gè)值;
  4. 支持鏈?zhǔn)椒椒ㄕ{(diào)用,相比于調(diào)用 Setter 方法,代碼更簡潔。

主要缺點(diǎn):

  1. 代碼量較大,多定義了一個(gè) Builder 類,多定義了一套屬性字段,多實(shí)現(xiàn)了一套賦值方法;
  2. 運(yùn)行效率低,需要先創(chuàng)建 Builder 實(shí)例,再賦值屬性字段,再創(chuàng)建目標(biāo)實(shí)例,最后拷貝屬性字段。

當(dāng)然,以上代碼,就可以通過 Lombok 的 @Builder 簡化代碼

如果我們就那么三三兩兩個(gè)參數(shù),直接構(gòu)造函數(shù)配合 set 方法就能搞定的,就不用套所謂的模式了。

高射炮打蚊子——不合算

假設(shè)有這樣一個(gè)復(fù)雜對象, 在對其進(jìn)行構(gòu)造時(shí)需要對諸多成員變量和嵌套對象進(jìn)行繁復(fù)的初始化工作。這些初始化代碼通常深藏于一個(gè)包含眾多參數(shù)且讓人基本看不懂的構(gòu)造函數(shù)中;甚至還有更糟糕的情況, 那就是這些代碼散落在客戶端代碼的多個(gè)位置。

這時(shí)候才是構(gòu)造器模式上場的時(shí)候

上邊的例子,其實(shí)屬于簡化版的建造者模式,只是為了方便構(gòu)建類中的各個(gè)參數(shù),”正經(jīng)“的和這個(gè)有點(diǎn)差別,更傾向于用同樣的構(gòu)建過程分步創(chuàng)建不同的產(chǎn)品類。

我們接著扯~

結(jié)構(gòu)

從 UML 圖上可以看到有 4 個(gè)不同的角色

  • 抽象建造者(Builder):創(chuàng)建一個(gè) Produc 對象的各個(gè)部件指定的接口/抽象類
  • 具體建造者(ConcreteBuilder):實(shí)現(xiàn)接口,構(gòu)建和裝配各個(gè)組件
  • 指揮者/導(dǎo)演類(Director):構(gòu)建一個(gè)使用 Builder 接口的對象。負(fù)責(zé)調(diào)用適當(dāng)?shù)慕ㄔ煺邅斫M建產(chǎn)品,導(dǎo)演類一般不與產(chǎn)品類發(fā)生依賴關(guān)系,與導(dǎo)演類直接交互的是建造者類。
  • 產(chǎn)品類(Product):一個(gè)具體的產(chǎn)品對象

demo

假設(shè)我是個(gè)汽車工廠,需求就是能造各種車(或者造電腦、造房子、做煎餅、生成不同文件TextBuilder、HTMLBuilder等等,都是一個(gè)道理)

1、生成器(Builder)接口聲明在所有類型生成器中通用的產(chǎn)品構(gòu)造步驟

  1. public interface CarBuilder { 
  2.     void setCarType(CarType type); 
  3.     void setSeats(int seats); 
  4.     void setEngine(Engine engine); 
  5.     void setGPS(GPS gps); 

2、具體的生成器(Concrete Builders)提供構(gòu)造過程的不同實(shí)現(xiàn)

  1. public class SportsCarBuilder implements CarBuilder { 
  2.  
  3.     private CarType carType; 
  4.     private int seats; 
  5.     private Engine engine; 
  6.     private GPS gps; 
  7.  
  8.     @Override 
  9.     public void setCarType(CarType type) { 
  10.         this.carType = type; 
  11.     } 
  12.  
  13.     @Override 
  14.     public void setSeats(int seats) { 
  15.         this.seats = seats; 
  16.     } 
  17.  
  18.     @Override 
  19.     public void setEngine(Engine engine) { 
  20.         this.engine = engine; 
  21.     } 
  22.  
  23.     @Override 
  24.     public void setGPS(GPS gps) { 
  25.         this.gps = gps; 
  26.     } 
  27.  
  28.     public Car getResult() { 
  29.         return new Car(carType, seats, engine, gps); 
  30.     } 

3、產(chǎn)品(Products)是最終生成的對象

  1. @Setter 
  2. @Getter 
  3. @ToString 
  4. public class Car { 
  5.  
  6.     private final CarType carType; 
  7.     private final int seats; 
  8.     private final Engine engine; 
  9.     private final GPS gps; 
  10.     private double fuel; 
  11.  
  12.     public Car(CarType carType,int seats,Engine engine,GPS gps){ 
  13.         this.carType = carType; 
  14.         this.seats = seats; 
  15.         this.engine = engine; 
  16.         this.gps = gps; 
  17.     } 

4、主管(Director)類定義調(diào)用構(gòu)造步驟的順序,這樣就可以創(chuàng)建和復(fù)用特定的產(chǎn)品配置(Director 類的構(gòu)造函數(shù)的參數(shù)是 CarBuilder,但實(shí)際上沒有實(shí)例傳遞出去作參數(shù),因?yàn)?CarBuilder 是接口或抽象類,無法產(chǎn)生對象實(shí)例,實(shí)際傳遞的是 Builder 的子類,根據(jù)子類類型,決定生產(chǎn)內(nèi)容)

  1. public class Director { 
  2.  
  3.     public void constructSportsCar(CarBuilder builder){ 
  4.         builder.setCarType(CarType.SPORTS_CAR); 
  5.         builder.setSeats(2); 
  6.         builder.setEngine(new Engine(2.0,0)); 
  7.         builder.setGPS(new GPS()); 
  8.     } 
  9.  
  10.     public void constructCityCar(CarBuilder builder){ 
  11.         builder.setCarType(CarType.CITY_CAR); 
  12.         builder.setSeats(4); 
  13.         builder.setEngine(new Engine(1.5,0)); 
  14.         builder.setGPS(new GPS()); 
  15.     } 
  16.  
  17.     public void constructSUVCar(CarBuilder builder){ 
  18.         builder.setCarType(CarType.SUV); 
  19.         builder.setSeats(4); 
  20.         builder.setEngine(new Engine(2.5,0)); 
  21.         builder.setGPS(new GPS()); 
  22.     } 
  23.  

5、客戶端使用(最終結(jié)果從建造者對象中獲取,主管并不知道最終產(chǎn)品的類型)

  1. public class Client { 
  2.  
  3.     public static void main(String[] args) { 
  4.         Director director = new Director(); 
  5.         SportsCarBuilder builder = new SportsCarBuilder(); 
  6.         director.constructSportsCar(builder); 
  7.  
  8.         Car car = builder.getResult(); 
  9.         System.out.println(car.toString()); 
  10.     } 

適用場景

適用場景其實(shí)才是理解設(shè)計(jì)模式最重要的,只要知道這個(gè)業(yè)務(wù)場景需要什么模式,網(wǎng)上浪~程序員能不會(huì)嗎

  • 使用建造者模式可避免重疊構(gòu)造函數(shù)的出現(xiàn)。

假設(shè)你的構(gòu)造函數(shù)中有 N 個(gè)可選參數(shù),那 new 各種實(shí)例的時(shí)候就很麻煩,需要重載構(gòu)造函數(shù)多次

  • 當(dāng)你希望使用代碼創(chuàng)建不同形式的產(chǎn)品 (例如石頭或木頭房屋) 時(shí), 可使用建造者模式。

如果你需要?jiǎng)?chuàng)建的各種形式的產(chǎn)品, 它們的制造過程相似且僅有細(xì)節(jié)上的差異, 此時(shí)可使用建造者模式。

  • 使用生成器構(gòu)造組合樹或其他復(fù)雜對象。

建造者模式讓你能分步驟構(gòu)造產(chǎn)品。你可以延遲執(zhí)行某些步驟而不會(huì)影響最終產(chǎn)品。你甚至可以遞歸調(diào)用這些步驟, 這在創(chuàng)建對象樹時(shí)非常方便。

VS 抽象工廠

抽象工廠模式實(shí)現(xiàn)對產(chǎn)品家族的創(chuàng)建,一個(gè)產(chǎn)品家族是這樣的一系列產(chǎn)品:具有不同分類維度的產(chǎn)品組合,采用抽象工廠模式不需要關(guān)心抽象過程,只關(guān)心什么產(chǎn)品由什么工廠生產(chǎn)即可。而建造者模式則是要求按照指定的藍(lán)圖建造產(chǎn)品,它的主要目的是通過組裝零配件而生產(chǎn)一個(gè)新的產(chǎn)品。

最后

設(shè)計(jì)模式,這玩意看簡單的例子,肯定能看得懂,主要是結(jié)合自己的業(yè)務(wù)思考怎么應(yīng)用,讓系統(tǒng)設(shè)計(jì)更完善,懂了每種模式后,可以找找各種框架源碼或在 github 搜搜相關(guān)內(nèi)容,看看實(shí)際中是怎么應(yīng)用的。

參考

 

refactoringguru.cn

 

責(zé)任編輯:武曉燕 來源: JavaKeeper
相關(guān)推薦

2020-10-20 13:33:00

建造者模式

2021-10-26 00:21:19

設(shè)計(jì)模式建造者

2021-01-21 05:34:14

設(shè)計(jì)模式建造者

2021-05-11 08:54:59

建造者模式設(shè)計(jì)

2021-04-14 09:02:22

模式 設(shè)計(jì)建造者

2011-07-14 14:46:46

設(shè)計(jì)模式

2021-07-28 10:02:54

建造者模式代碼

2024-02-19 08:38:34

建造者模式Android設(shè)計(jì)模式

2022-11-01 15:25:01

構(gòu)建者模式Go 語言

2025-04-25 08:23:20

2020-11-23 10:02:04

開發(fā)者

2020-11-16 22:04:20

開發(fā)者

2023-11-08 14:45:14

AIGC生成式人工智能

2022-10-09 08:48:13

配置化建造者參數(shù)

2023-06-05 18:25:52

物聯(lián)網(wǎng)大數(shù)據(jù)

2010-08-27 10:34:51

程序員

2017-06-26 09:40:50

Python代碼寫法

2017-07-07 16:57:35

代碼Python

2021-07-20 08:52:20

命令模式中介者模式設(shè)計(jì)模式

2020-11-05 09:38:07

中介者模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 精品久久久久久 | 成人在线精品视频 | 国产乱码精品一品二品 | 男女精品网站 | 国产精品成人国产乱 | 国产综合在线视频 | 蜜桃视频一区二区三区 | 中文字幕视频一区二区 | 国产一区二区在线免费观看 | 天堂一区二区三区 | 亚洲精品久久久久久宅男 | 欧美 中文字幕 | 中文字幕在线一区二区三区 | 国产精品久久久久久久免费观看 | 91精品国产乱码久久久久久 | 久久av一区二区三区 | 亚洲高清视频一区二区 | 亚洲欧洲色视频 | 五月婷六月丁香 | 亚洲欧美一区二区三区国产精品 | cao视频 | 日韩成人免费 | 国产欧美日韩一区二区三区 | 国产在线不卡视频 | 在线观看涩涩视频 | 黄网站涩免费蜜桃网站 | 国产日韩视频在线 | 成人小视频在线观看 | 国产一区二区三区四区五区3d | 狠狠干夜夜草 | 亚洲国产aⅴ成人精品无吗 亚洲精品久久久一区二区三区 | 日韩三级在线 | 亚洲美乳中文字幕 | 亚洲精品大片 | 久久综合久 | 黄网站涩免费蜜桃网站 | 国产97色| 成人毛片视频免费 | 中文字幕一区二区三区不卡 | 中文字幕成人 | 毛片一区二区三区 |