java的Builder原理和實現詳解

首先給一個簡單的Builder設計模式的例子:

主實現類代碼如下:

/**
 * 實體類 包含一個靜態內部類 Builder
 */
public class CompanyClient {
    public String companyName;
    // 用final修飾的成員變量表示常量,隻能被賦值一次,賦值後值無法改變! final修飾的變量有三種:靜態變量、實例變量和局部變量。
    public String companyAddress;
  
    public double companyRegfunds;
    public String mPerson;
    public String mType;     
     //構造方法 
     public CompanyClient() {
         this(new Builder());
     }
     //構造方法
     public CompanyClient(Builder builder){
         this.companyName = builder.companyName;
         this.companyAddress = builder.companyAddress;
         this.companyRegfunds = builder.companyRegfunds;
         this.mPerson = builder.person;
         this.mType = builder.type;
     }
     public String getCompanyName() {
         return companyName;
     }
  
     public String getCompanyAddress() {
         return companyAddress;
     }
  
     public double getCompanyRegfunds() {
         return companyRegfunds;
     }
  
     public String getmPerson() {
         return mPerson;
     }
  
     public String getmType() {
         return mType;
     }
         
     public Builder newBuilder() {
         return new Builder(this);
     }
  
     @Override //重寫toString方法後,當print這個對象的時候,會默認的調用toString()這個方法。
     public String toString() {
         return "CompanyClient{" +
                 "companyName='" + companyName + '\'' +
                 ", companyAddress='" + companyAddress + '\'' +
                 ", companyRegfunds=" + companyRegfunds +"千萬"+
                 ", mPerson=" + mPerson +
                 ", mType='" + mType + '\'' +
                 '}';
     }
     /**
     *靜態內部類 Builder
     */
     public static class Builder{
        public String companyName;
        public String companyAddress;
        public  double companyRegfunds;
        public  String person;
        public String type;
        //構造方法
        public Builder() {
            companyName = companyName;
            companyAddress = companyAddress;
            companyRegfunds = companyRegfunds;
            person = person;
            type = type;
  
        }
        //構造方法
        Builder(CompanyClient companyClient){
            this.companyName = companyClient.companyName;
            this.companyAddress = companyClient.companyAddress;
            this.companyRegfunds = companyClient.companyRegfunds;
            this.person = companyClient.mPerson;
            this.type = companyClient.mType;
        }
  
        public Builder setCompanyName(String name) {
            companyName = name;
            return this;
        }
  
        public Builder setCompanyAddress(String address) {
            companyAddress = address;
            return this;
        }
  
        public Builder setCompanyRegfunds(double regfunds) {
            companyRegfunds = regfunds;
            return this;
        }
  
        public Builder setmPerson(String per) {
            person = per;
            return this;
        }
  
        public Builder setmType(String typeStr) {
            type = typeStr;
            return this;
        }
         //構建一個實體
         public CompanyClient build() {
             return new CompanyClient(this);
         }
    }
 }

測試類實現代碼如下:

public class TestBuilder {
    public static void main(String[] args) {
 
        CompanyClient client = new CompanyClient.Builder()
                .setCompanyName("alibaba")
                .setCompanyAddress("wangjing")
                .setCompanyRegfunds(5)
                .setmPerson("10000")
                .build();
        System.out.println(client);
        System.out.println("---------------------");
        CompanyClient.Builder builder = new CompanyClient.Builder();
        builder.setCompanyName("huawei");
        builder.setCompanyAddress("haidian");
        builder.setCompanyRegfunds(20);
        builder.setmType("communication");
        CompanyClient client1 = builder.build();
        System.out.println(client1);
        System.out.println("---------------------");
        CompanyClient.Builder build1 = client1.newBuilder();
        build1.setCompanyName("baidu");
        CompanyClient client2 = build1.build();
        System.out.println(client2);
    }
}

輸出結果如下:

CompanyClient{companyName='alibaba', companyAddress='wangjing', companyRegfunds=5.0千萬, mPerson=10000, mType='null'}
---------------------
CompanyClient{companyName='huawei', companyAddress='haidian', companyRegfunds=20.0千萬, mPerson=null, mType='communication'}
---------------------
CompanyClient{companyName='baidu', companyAddress='haidian', companyRegfunds=20.0千萬, mPerson=null, mType='communication'}

首先看main函數中的第一行代碼:

CompanyClient client = new CompanyClient.Builder()
                .setCompanyName("alibaba")
                .setCompanyAddress("wangjing")
                .setCompanyRegfunds(5)
                .setmPerson("10000")
                .build();

之所以可以這麼執行,是因為內部靜態類Builder裡定義瞭一份與CompanyClient類一模一樣的變量,通過一系列的成員函數進行設置屬性值,但是返回值都是this,也就是都是Builder對象,最後提供瞭一個build函數用於創建CompanyClient對象,返回的是CompanyClient對象,對應的構造函數在CompanyClient 類中進行定義,也就是構造函數的入參是Builder對象,然後依次對自己的成員變量進行賦值,對應的值都是Builder對象中的值。此外Builder類中的成員函數返回Builder對象自身的另一個作用就是讓它支持鏈式調用,使代碼可讀性大大增強。

總結下,Java環境下builder設計模式:

定義一個靜態內部類Builder,內部的成員變量和外部類一樣

Builder類通過一系列的方法用於成員變量的賦值,並返回當前對象本身(this)

Builder類提供一個build方法或者create方法用於創建對應的外部類,該方法內部調用瞭外部類的一個私有構造函數,該構造函數的參數就是內部類Builder

外部類提供一個私有構造函數供內部類調用,在該構造函數中完成成員變量的賦值,取值為Builder對象中對應的值

到此這篇關於java的Builder原理和實現詳解的文章就介紹到這瞭,更多相關java Builder原理和實現內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: