Java的Builder模式初識(shí)

2016年過(guò)去了,新的一年來(lái)了,大家過(guò)的怎樣呢?16年的小目標(biāo)實(shí)現(xiàn)了嗎?別急,到了17年,你會(huì)發(fā)現(xiàn),還是實(shí)現(xiàn)不了,哈哈哈哈~~~別打我

最近一直在負(fù)責(zé)網(wǎng)絡(luò)框架和數(shù)據(jù)處理部分,也遇到了不少坑,今天就跟大家分享下


大家都知道,我們和服務(wù)器交互的時(shí)候,服務(wù)器返回Json數(shù)據(jù)之后,我們都會(huì)生成對(duì)應(yīng)的實(shí)體類(lèi)去存儲(chǔ)數(shù)據(jù),就是我們所說(shuō)的JavaBean,而對(duì)應(yīng)類(lèi)而言,為了讓客戶(hù)端更容易的去獲取到它的實(shí)例,通常我們都是提供一個(gè)構(gòu)造方法去給別的類(lèi)調(diào)用,但是,我們想下,假如服務(wù)器返回了N個(gè)屬性,我們?cè)诰帉?xiě)實(shí)體類(lèi)的時(shí)候,常用的方式就是寫(xiě)N個(gè)屬性,然后分別生成對(duì)應(yīng)的get和set方法,然后我們別的類(lèi)調(diào)用set方法的時(shí)候,就有下面兩種方式:

1,直接在構(gòu)造方法中傳入

public class LoginBean { 
   private String id;   
   private int uid;   
   private String name; 
   private String mobile;   
   private String portrait;   
   private String realName;   
   public LoginBean(String id,int uid,String name,String mobile,Strin   
                               portrait,String realName){      
                  this.id=id;   
                    //此處省略
                  this.realName=realName;   
 }

2,就是實(shí)例化類(lèi),然后通過(guò)set的方法寫(xiě)入數(shù)據(jù)

LoginBean bean = new LoginBean();
bean.setId(xxx);
//此處省略
bean.setRealName(xxx);

現(xiàn)在我們考慮下,就第一種方式來(lái)說(shuō),假如我有多個(gè)類(lèi)去調(diào)用這個(gè)實(shí)體類(lèi),但是每個(gè)類(lèi)所需要的入?yún)⒍疾灰粯?,有的可?個(gè),有的可能3個(gè),有的可能不需要,如果是按照這個(gè)構(gòu)造方式傳入的話,那么我就必定要傳入N個(gè)參,不需要的參就設(shè)置默認(rèn)值或者null,這時(shí)候有人說(shuō),那我可以提供多個(gè)構(gòu)造方法啊,我覺(jué)得這就是最笨的方法,當(dāng)屬性多的時(shí)候,那就需要多個(gè)構(gòu)造,不僅增加的代碼量,而且還不利于擴(kuò)展,并且當(dāng)別人接手你項(xiàng)目的時(shí)候,也不利于閱讀

如果是第二種方式,的確是比第一種方式好多,不需要多個(gè)構(gòu)造方法,只需在用到的時(shí)候set進(jìn)去就可以,閱讀也方便,但是,遺憾的一點(diǎn)是,JavaBean模式自身就有著比較嚴(yán)重的缺點(diǎn),因?yàn)闃?gòu)造過(guò)程中會(huì)被分到了幾個(gè)調(diào)用中,所以在構(gòu)造之中可能處于不一致,并且還有一點(diǎn)就是,JavaBean阻止了把類(lèi)做成不可變的可能,想了解什么是不可變類(lèi)和可變類(lèi),可以參考下這篇博客:https://my.oschina.net/zzw922cn/blog/487610
簡(jiǎn)單來(lái)說(shuō)就是,不可變類(lèi)就是每個(gè)實(shí)例中所包含的信息必須在創(chuàng)建完成時(shí)就提供,并且在對(duì)象的整個(gè)生命周期內(nèi)固定不變,不可變的類(lèi)比可變類(lèi)更加實(shí)現(xiàn),使用,也不容易出錯(cuò),具體自己可以去了解下,這里不做深入的說(shuō)明

第二種方式是在構(gòu)造完成之后,在去寫(xiě)入值,跟不可變類(lèi)就相反了,那么有沒(méi)有一種方式,既可以保證不需要像第一種方式那樣編寫(xiě)多個(gè)構(gòu)造,又能解決第二種方式的問(wèn)題呢?這就本文的重點(diǎn),Builder模式


Builder模式

Builder模式又叫構(gòu)造者模式,既然我們既要像第一種方式那樣可以直接在構(gòu)造器入?yún)?,又要避免第二種方式的問(wèn)題,是不是有點(diǎn)棘手呢?它是怎么實(shí)現(xiàn)這種處理的呢?先看它的實(shí)現(xiàn)

public class Test {  
  private final String id;   
  private final String uid;   

  private Test(Builder builder) {   
     this.id = builder.id;     
     this.uid = builder.uid;   
 }   
 public static class Builder {        
    private String id;      
    private String uid;       

 public Builder setId(String id) {      
       this.id = id;           
       return this;      
  }       
 public Builder setUid(String uid) {        
    this.uid = uid;           
    return this;        
}        
 public Test build() {         
   return new Test(this);       
}     

   @Override       
   public String toString() {      
      return "Builder{" +            
        "id='" + id + '\'' +             
       ", uid='" + uid + '\'' +         
           '}';       
   }   
 }   
 @Override    
 public String toString() {      
  return "Test{" +         
       "id='" + id + '\'' +        
       ", uid='" + uid + '\'' +         
       '}';  
  }
} 

我們不難發(fā)現(xiàn),我們并沒(méi)有直接生成想要的對(duì)象,而是讓客戶(hù)端利用所有必要的參數(shù)調(diào)用構(gòu)造器,得到一個(gè)builder對(duì)象,然后再調(diào)用builder的set中方法,來(lái)設(shè)置參數(shù),這樣就保證了在生成實(shí)例的時(shí)候直接就綁定了數(shù)據(jù),我們看看怎么調(diào)用:

public static void main(String [] args){   
 Test test = new Test.Builder()
                .setId("0")
                .setUid("fadf")
                .build();    
 System.out.print(test.toString());
}

是不是很像Rxjava的連式結(jié)構(gòu),客戶(hù)端調(diào)用無(wú)參的build方法生成了對(duì)象,因?yàn)樵谏蓪?duì)象之前就已經(jīng)把數(shù)據(jù)set進(jìn)去了,這就保證了類(lèi)的不可變,也就是說(shuō),當(dāng)我們需要重新去set數(shù)據(jù)的時(shí)候,得重新去生成新的對(duì)象然后進(jìn)行build,還有的是,這樣的代碼更加的清晰,便于閱讀,并且很靈活,builder可以有多個(gè)可變的參數(shù),這也解決了第一種生成多個(gè)構(gòu)造器的問(wèn)題,總而言之,如果類(lèi)的構(gòu)造器具有多個(gè)參數(shù)或者參數(shù)多變的情況下,這樣設(shè)計(jì)就是個(gè)不錯(cuò)的選擇

好了,這篇文章就到這來(lái),祝大家新的一年了,新年快樂(lè),工作順利,也祝大家雞年大吉吧,嘿嘿嘿~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,687評(píng)論 18 399
  • Java 語(yǔ)言支持的類(lèi)型分為兩類(lèi):基本類(lèi)型和引用類(lèi)型。整型(byte 1, short 2, int 4, lon...
    xiaogmail閱讀 1,448評(píng)論 0 10
  • 前言 人生苦多,快來(lái) Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類(lèi)型編程...
    任半生囂狂閱讀 26,692評(píng)論 9 118
  • 1.import static是Java 5增加的功能,就是將Import類(lèi)中的靜態(tài)方法,可以作為本類(lèi)的靜態(tài)方法來(lái)...
    XLsn0w閱讀 1,427評(píng)論 0 2
  • 習(xí)慣性失眠,第三晚。突然想起不遠(yuǎn)不近畢業(yè)照時(shí)的一個(gè)淡淡的記憶。一向惡劣的人竟把鞭炮帶到學(xué)校點(diǎn)燃,隨著炮聲的炸響,在...
    雷光閃閃閱讀 172評(píng)論 0 0

友情鏈接更多精彩內(nèi)容