最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java設(shè)計(jì)模式之建造者模式淺析示例

 更新時(shí)間:2022年11月28日 11:54:08   作者:lpf_wei  
建造者模式,是一種對(duì)象構(gòu)建模式 它可以將復(fù)雜對(duì)象的建造過程抽象出來,使這個(gè)抽象過程的不同實(shí)現(xiàn)方法可以構(gòu)造出不同表現(xiàn)的對(duì)象。本文將通過示例講解建造者模式,需要的可以參考一下

編程是一門藝術(shù),大批量的改動(dòng)顯然是非常丑陋的做法,用心的琢磨寫的代碼讓它變的更美觀。

1.建造者(Builder)設(shè)計(jì)模式定義

建造者設(shè)計(jì)模式是指將一個(gè)復(fù)雜對(duì)象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示,這樣的被稱為建造者模式。

它是將一個(gè)復(fù)雜的對(duì)象分解為多個(gè)簡(jiǎn)單的對(duì)象,然后一步一步構(gòu)建而成。它將變與不變相分離,即產(chǎn)品的組成部分是不變的,但每一部分是可以靈活選擇的。

2.建造者設(shè)計(jì)模式優(yōu)點(diǎn)

  • 封裝性好,構(gòu)建和表示分離。
  • 擴(kuò)展性好,各個(gè)具體的建造者相互獨(dú)立,有利于系統(tǒng)的解耦。
  • 客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié),建造者可以對(duì)創(chuàng)建過程逐步細(xì)化,而不對(duì)其它模塊產(chǎn)生任何影響,便于控制細(xì)節(jié)風(fēng)險(xiǎn)。

3.建造者設(shè)計(jì)模式不足之處

  • 產(chǎn)品的組成部分必須相同,這限制了其使用范圍。
  • 如果產(chǎn)品的內(nèi)部變化復(fù)雜,如果產(chǎn)品內(nèi)部發(fā)生變化,則建造者也要同步修改,后期維護(hù)成本較大。

4.建造者設(shè)計(jì)模式角色關(guān)系

建造者(Builder)模式由產(chǎn)品、抽象建造者、具體建造者、指揮者等 4 個(gè)要素構(gòu)成。

  • 產(chǎn)品角色(Product):它是包含多個(gè)組成部件的復(fù)雜對(duì)象,由具體建造者來創(chuàng)建其各個(gè)零部件。
  • 抽象建造者(Builder):它是一個(gè)包含創(chuàng)建產(chǎn)品各個(gè)子部件的抽象方法的接口,通常還包含一個(gè)返回復(fù)雜產(chǎn)品的方法 getResult()。
  • 具體建造者(Concrete Builder):實(shí)現(xiàn) Builder 接口,完成復(fù)雜產(chǎn)品的各個(gè)部件的具體創(chuàng)建方法。
  • 指揮者(Director):它調(diào)用建造者對(duì)象中的部件構(gòu)造與裝配方法完成復(fù)雜對(duì)象的創(chuàng)建,在指揮者中不涉及具體產(chǎn)品的信息。

5.建造者設(shè)計(jì)模式應(yīng)用

建造者設(shè)計(jì)模式應(yīng)用非常廣泛,比如Retrofit、AlertDialog等都使用了建造者設(shè)計(jì)模式。

下面使用Retrofit刪減版本當(dāng)作示例(這是一個(gè)開源項(xiàng)目的真實(shí)場(chǎng)景,更加貼近真實(shí)的應(yīng)用)

public final class Retrofit {
      Retrofit(
      	okhttp3.Call.Factory callFactory,
     	HttpUrl baseUrl,
      	List<Converter.Factory> converterFactories,
      	int defaultConverterFactoriesSize,
      	List<CallAdapter.Factory> callAdapterFactories,
      	int defaultCallAdapterFactoriesSize,
      	@Nullable Executor callbackExecutor,
      	boolean validateEagerly) {
    		this.callFactory = callFactory;
   		 this.baseUrl = baseUrl;
   		 this.converterFactories = converterFactories;  
    	 this.defaultConverterFactoriesSize = defaultConverterFactoriesSize;
   		 this.callAdapterFactories = callAdapterFactories; 
    	 this.defaultCallAdapterFactoriesSize = defaultCallAdapterFactoriesSize;
         this.callbackExecutor = callbackExecutor;
         this.validateEagerly = validateEagerly;
 	 }
      public static final class Builder {
      		 public Builder() {}
             public Builder baseUrl(URL baseUrl) {
      			Objects.requireNonNull(baseUrl, "baseUrl == null");
     		 	return baseUrl(HttpUrl.get(baseUrl.toString()));
    		}
          public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      			callAdapterFactories.add(Objects.requireNonNull(factory, "factory 					== null"));
      			return this;
    		}
             public Builder addConverterFactory(Converter.Factory factory) 	{
      				converterFactories.add(Objects.requireNonNull(factory, "factory == 						null"));
      				return this;
   			 }
    		public Retrofit build() {
    			if (baseUrl == null) {
       		 		throw new IllegalStateException("Base URL required.");
      			}
      			Platform platform = Platform.get();
     			okhttp3.Call.Factory callFactory = this.callFactory;
      			if (callFactory == null) {
        			callFactory = new OkHttpClient();
     		 	}
      			Executor callbackExecutor = this.callbackExecutor;
      			if (callbackExecutor == null) {
        			callbackExecutor = platform.defaultCallbackExecutor();
      			}
      			converterFactories.add(new BuiltInConverters());
      			converterFactories.addAll(this.converterFactories);
      			converterFactories.addAll(defaultConverterFactories);
     		 return new Retrofit(
          		baseUrl,
          		unmodifiableList(converterFactories),
          		defaultConverterFactoriesSize,
          		unmodifiableList(callAdapterFactories),
          		defaultCallAdapterFactories.size(),
          		callbackExecutor,
          		validateEagerly);
    		}
  		}
     }
}
//Retrofit 對(duì)象的創(chuàng)建
 Retrofit retrofit =
        new Retrofit.Builder()
            .baseUrl(API_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

Retrifit官網(wǎng)地址:https://github.com/square/retrofit

以上內(nèi)容做了刪減,只為說明建造者設(shè)計(jì)模式,以上例子中產(chǎn)品角色就是Retrofit,這里Builder就是具體的建造者,當(dāng)用戶使用的時(shí)候,只需要通過建造者設(shè)置具體屬性,比如URL、ConverterFactory等,然后調(diào)用build方法就可以創(chuàng)建Retrofit對(duì)象。

在案例中可以看到,除了URL是必須要添加的之外,其他的都是有默認(rèn)值的,如果不設(shè)置也沒有問題。這樣就可以通過設(shè)置不同的參數(shù),創(chuàng)建出各種各樣的Retrofit對(duì)象了,靈活方便。

建造者模式在應(yīng)用過程中可以根據(jù)需要改變,如果創(chuàng)建的產(chǎn)品種類只有一種,只需要一個(gè)具體建造者,這時(shí)可以省略掉抽象建造者,甚至可以省略掉指揮者角色。以上就是這樣的案例。

6.建造者設(shè)計(jì)模式的應(yīng)用場(chǎng)景

建造者模式唯一區(qū)別于工廠模式的是針對(duì)復(fù)雜對(duì)象的創(chuàng)建。也就是說,如果創(chuàng)建簡(jiǎn)單對(duì)象,通常都是使用工廠模式進(jìn)行創(chuàng)建,而如果創(chuàng)建復(fù)雜對(duì)象,就可以考慮使用建造者模式。

當(dāng)需要?jiǎng)?chuàng)建的產(chǎn)品具備復(fù)雜創(chuàng)建過程時(shí),可以抽取出共性創(chuàng)建過程,然后交由具體實(shí)現(xiàn)類自定義創(chuàng)建流程,使得同樣的創(chuàng)建行為可以生產(chǎn)出不同的產(chǎn)品,分離了創(chuàng)建與表示,使創(chuàng)建產(chǎn)品的靈活性大大增加。

建造者模式主要適用于以下應(yīng)用場(chǎng)景:

  • 相同的方法,不同的執(zhí)行順序,產(chǎn)生不同的結(jié)果。
  • 多個(gè)部件或零件,都可以裝配到一個(gè)對(duì)象中,但是產(chǎn)生的結(jié)果又不相同。
  • 產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中不同的調(diào)用順序產(chǎn)生不同的作用。
  • 初始化一個(gè)對(duì)象特別復(fù)雜,參數(shù)多,而且很多參數(shù)都具有默認(rèn)值。

到此這篇關(guān)于Java設(shè)計(jì)模式之建造者模式淺析示例的文章就介紹到這了,更多相關(guān)Java建造者模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 線程中start方法與run方法的區(qū)別詳細(xì)介紹

    java 線程中start方法與run方法的區(qū)別詳細(xì)介紹

    這篇文章主要介紹了java 線程中start方法與run方法的區(qū)別詳細(xì)介紹的相關(guān)資料,在java線程中調(diào)用start方法與run方法的區(qū)別在哪里? 這兩個(gè)問題是兩個(gè)非常流行的初學(xué)者級(jí)別的多線程面試問題,這里進(jìn)行詳細(xì)說明,需要的朋友可以參考下
    2016-11-11
  • Java線程池使用AbortPolicy策略

    Java線程池使用AbortPolicy策略

    這篇文章主要介紹了?Java線程池使用AbortPolicy策略,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-06-06
  • 詳解PowerDesigner之CDM、PDM、SQL之間轉(zhuǎn)換

    詳解PowerDesigner之CDM、PDM、SQL之間轉(zhuǎn)換

    這篇文章主要介紹了詳解PowerDesigner之CDM、PDM、SQL之間轉(zhuǎn)換的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • Spring Boot jar中沒有主清單屬性的解決方法

    Spring Boot jar中沒有主清單屬性的解決方法

    這篇文章主要介紹了Spring Boot jar中沒有主清單屬性的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • java.exe和javaw.exe的區(qū)別及使用方法

    java.exe和javaw.exe的區(qū)別及使用方法

    這篇文章主要介紹了java.exe和javaw.exe的區(qū)別及使用方法,需要的朋友可以參考下
    2014-04-04
  • 解決netty中spring對(duì)象注入失敗的問題

    解決netty中spring對(duì)象注入失敗的問題

    這篇文章主要介紹了解決netty中spring對(duì)象注入失敗的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • maven中resource配置使用詳解

    maven中resource配置使用詳解

    這篇文章主要介紹了maven中resource配置使用,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java Swing實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)源碼(收藏版)

    Java Swing實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)源碼(收藏版)

    這篇文章主要介紹了Java Swing實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)源碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • java對(duì)象轉(zhuǎn)化成String類型的四種方法小結(jié)

    java對(duì)象轉(zhuǎn)化成String類型的四種方法小結(jié)

    在java項(xiàng)目的實(shí)際開發(fā)和應(yīng)用中,常常需要用到將對(duì)象轉(zhuǎn)為String這一基本功能。本文就詳細(xì)的介紹幾種方法,感興趣的可以了解一下
    2021-08-08
  • springboot swagger2注解使用的教程

    springboot swagger2注解使用的教程

    這篇文章主要介紹了springboot swagger2注解使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05

最新評(píng)論

阿坝县| 肃南| 扎赉特旗| 利川市| 黔东| 青海省| 泗水县| 高州市| 磐安县| 古交市| 全州县| 永新县| 汝阳县| 平江县| 三河市| 安丘市| 页游| 莱阳市| 大新县| 乌审旗| 连云港市| 宣威市| 马公市| 金溪县| 大渡口区| 广宁县| 丹江口市| 清镇市| 民权县| 喀喇沁旗| 乌兰察布市| 乐东| 农安县| 深水埗区| 黔西县| 安仁县| 阿拉善盟| 五家渠市| 文昌市| 贵阳市| 酉阳|