設計模式- 建造者模式

 

建造模式

介紹

該子標題中內容,來源菜鳥教程

意圖

將一個複雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。

主要解決

主要解決在軟件系統中,有時候面臨着"一個複雜對象"的創建工作,其通常由各個部分的子對象用一定的算法構成;由於需求的變化,這個複雜對象的各個部分經常面臨着劇烈的變化,但是將它們組合在一起的算法卻相對穩定。

何時使用

一些基本部件不會變,而其組合經常變化的時候。

如何解決

將變與不變分離開。

優點

  1. 建造者獨立,易擴展。

  2. 便於控制細節風險。

缺點:

  1. 產品必須有共同點,範圍有限制。

  2. 如內部變化複雜,會有很多的建造類。

使用場景

  1. 需要生成的對象具有複雜的內部結構。

  2. 需要生成的對象內部屬性本身相互依賴。

注意事項

與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。

代碼

模式角色和職責

產品對象

複雜的內部屬性集合的bean。
本文的例子:Company和CompanyPersonnel對象

抽象構建類

主要用來對產品的屬性進行構建
本文的例子:CompanyBuilder對象

具體的構建類

該類實現 【抽象構建類】 ,對產品中的屬性進行具體的創建
本文的例子:ATestCompanyBuilder對象

導演類

對產品進行具體的組裝。
【具體的構建類】指的是產品中的屬性進行構建,
而該類是獲取最終的產品對象
本文的例子:Director對象

場景

代碼含義

沒有複雜業務,簡單代碼展示,對一個公司和員工的 bean 進行構建。

代碼展示

產品對象

公司對象

package com.builderpattern.vo;


import lombok.Data;


import java.util.List;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: Company.java
 * @Description: 公司對象
 * @autho Admin
 * @date 2020/1/13 11:35
 */
@Data
public class Company {


    /**
     * 名稱
     */
    private String name;


    /**
     * 公司統一社會信用代碼(公司的唯一標識)
     */
    private String socialId;


    /**
     * 企業員工
     */
    private List<CompanyPersonnel> companyPersonnelList;
}


公司員工對象

package com.builderpattern.vo;


import lombok.Data;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: CompanyPersonnel.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 13:54
 */
@Data
public class CompanyPersonnel {


    /**
     * 員工姓名
     */
    private String name;


    /**
     * 員工編號
     */
    private String number;


    /**
     * 員工年齡
     */
    private Integer age;


    /**
     * 員工性別  0:男  1:女
     */
    private String sex;
}


抽象構建類

package com.builderpattern.build;


import com.builderpattern.vo.Company;
import com.builderpattern.vo.CompanyPersonnel;


import java.util.List;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: CompanyBuilder.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 13:56
 */
public abstract class CompanyBuilder {
    //創建公司對象(產品)
    protected Company company = new Company();


    /**
     * 產品屬性建造  公司名稱 可以通過外部傳入獲取
     * @return
     */
    public abstract CompanyBuilder buildName(String name);


    /**
     * 產品屬性建造  統一社會信用代碼
     * @return
     */
    public abstract CompanyBuilder buildSocialId();


    /**
     * 產品屬性建造  公司員工集合
     * @return
     */
    public abstract CompanyBuilder buildPersonnelList();


    /**
     * 提供一個方法,可以得到產品
     * @return
     */
    public Company getCompany(){
        return company;
    }
}

具體的構建類

package com.builderpattern.build;


import com.builderpattern.vo.CompanyPersonnel;
import org.apache.commons.lang3.RandomUtils;


import java.util.ArrayList;
import java.util.List;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: ATestCompanyBuilder.java
 * @Description: A測試公司建造
 * @autho Admin
 * @date 2020/1/13 14:04
 */
public class ATestCompanyBuilder extends CompanyBuilder{


    public CompanyBuilder buildName(String name) {
        company.setName(name);
        return this;
    }


    public CompanyBuilder buildSocialId() {
        company.setSocialId("91123123213213211A");
        return this;
    }


    public CompanyBuilder buildPersonnelList() {
        ArrayList<CompanyPersonnel> list = new ArrayList<CompanyPersonnel>();
        for (int i = 0; i < 10; i++) {
            CompanyPersonnel companyPersonnel = new CompanyPersonnel();
            companyPersonnel.setAge(18+i);
            companyPersonnel.setName("測試員工"+(i+1));
            companyPersonnel.setNumber(String.valueOf(i+1));
            companyPersonnel.setSex(i%2==0?"0":"1");
            list.add(companyPersonnel);
        }
        company.setCompanyPersonnelList(list);
        return this;
    }


}


導演類

package com.builderpattern.director;


import com.builderpattern.build.CompanyBuilder;
import com.builderpattern.vo.Company;
import lombok.Data;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: Director.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 14:19
 */
@Data
public class Director {
    //獲取build的基類對象,可以通過有參構造傳入
    private CompanyBuilder companyBuilder;


    public Director(CompanyBuilder companyBuilder){
        this.companyBuilder = companyBuilder;
    }


    //負責公司(產品)對象的創建
    public Company construct(String name){
        return companyBuilder.buildName(name)
                .buildPersonnelList()
                .buildSocialId()
                .getCompany();
    }
}

測試類

package com.builderpattern;


import com.builderpattern.build.ATestCompanyBuilder;
import com.builderpattern.build.CompanyBuilder;
import com.builderpattern.director.Director;
import com.builderpattern.vo.Company;


/**
 * @version v1.0
 * @Copyright(c): 2020-2020
 * @FileName: Test.java
 * @Description:
 * @autho Admin
 * @date 2020/1/13 14:23
 */
public class Test {
    public static void main(String[] args) {
        //創建建造者
        CompanyBuilder builder = new ATestCompanyBuilder();
        //通過Director統一組建,並獲取產品
        Director director = new Director(builder);
        Company construct = director.construct("A測試公司");


        System.out.println(construct);
    }
}


測試結果

Company(name=A測試公司, socialId=91123123213213211A,
companyPersonnelList=
[CompanyPersonnel(name=測試員工1, number=1, age=18, sex=0),
CompanyPersonnel(name=測試員工2, number=2, age=19, sex=1),
CompanyPersonnel(name=測試員工3, number=3, age=20, sex=0),
CompanyPersonnel(name=測試員工4, number=4, age=21, sex=1),
CompanyPersonnel(name=測試員工5, number=5, age=22, sex=0),
CompanyPersonnel(name=測試員工6, number=6, age=23, sex=1),
CompanyPersonnel(name=測試員工7, number=7, age=24, sex=0),
CompanyPersonnel(name=測試員工8, number=8, age=25, sex=1),
CompanyPersonnel(name=測試員工9, number=9, age=26, sex=0),
CompanyPersonnel(name=測試員工10, number=10, age=27, sex=1)])

什麼時候使用

本文產品中的成員變量比較少,如果在業務比較複雜,成員變量很多,需要的有參構造方法比較多(而且可能有的成員變量要使用,有的不要使用,很容易亂。使用 set 多了,也會亂),難以維護,就可以使用該模式

附:目錄結構

有需要源碼的,也可以掃描下方二維碼,加我好友,私聊我

- END -

推薦閱讀

● 抽象工廠模式

● 裝飾者模式

● 工廠模式

● 命令模式-接收者與執行者解耦和

● hexo-詳細搭建

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章