JAVA 設計模式(五)—— 設計模式之建造者模式

一、建造者模式概述

1、建造者模式介紹

(1)介紹

  • 建造者模式(Builder Pattern)又叫生成器模式,是一種對象構建模式,屬於創建型模式。
  • 建造者模式可以將複雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象。
  • 建造者模式使用多個簡單的對象一步一步構建成一個複雜的對象,它允許用戶只通過指定複雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。

(2)優缺點

  • 優點:
    • 建造者獨立,易擴展。
    • 便於控制細節風險。
    • 可以使客戶端不必知道產品內部組成的細節。
    • 具體的建造者類之間是相互獨立的,這有利於系統的擴展。
    • 具體的建造者相互獨立,因此可以對建造的過程逐步細化,而不會對其他模塊產生任何影響。
  • 缺點:
    • 建造者模式所創建的產品一般具有較多的共同點,其組成部分相似;如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
    • 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。

(3)使用場景

  • 隔離複雜對象的創建和使用,相同的方法,不同執行順序,產生不同事件結果;
  • 多個部件都可以裝配到一個對象中,但產生的運行結果不相同;
  • 產品類非常複雜或者產品類因爲調用順序不同而產生不同作用;
  • 初始化一個對象時,參數過多,或者很多參數具有默認值;
  • Builder模式不適合創建差異性很大的產品類;
  • 產品內部變化複雜,會導致需要定義很多具體建造者類實現變化,增加項目中類的數量,增加系統的理解難度和運行成本;
  • 需要生成的產品對象有複雜的內部結構,這些產品對象具備共性。

(4)注意事項

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

2、建造者模式的四個角色

(1)四個角色介紹

  • Product(產品角色) :一個具體的產品對象。
  • Builder(抽象建造者) :創建一個Product對象的各個部件指定的接口。
  • ConcreteBuilder(具體建造者):實現接口,構建和裝配各個部件。
  • Director(指揮者):構建一個使用Builder接口的對象。它主要是用於創建一個複雜的對象。它主要有兩個作用,一是隔離了客戶與對象的生產過程,二是負責控制產品對象的生產過程。

(2)四個角色原理類圖
在這裏插入圖片描述

二、建造者模式示例

1、建造者模式示例1

比如我們現在需要烹飪白菜,白菜有不同的做法,炒白菜的大概步驟有買菜、洗菜、炒菜,而辣白菜的步驟有買菜、洗菜、醃菜,白菜湯的步驟有買菜、洗菜、煮菜。
(1)首先創建一個類Product代表成品菜,類中包含具體的做菜步驟

public class Product {
    private String buyFood;     //買菜
    private String washFood;    //洗菜
    private String fireFood;    //炒菜
    private String saltFood;    //醃菜
    private String waterFood;   //煮菜
    /*省略getter/setter方法*/
}

(2)創建一個抽象建造者Builder 類,定義產品的創建方法和返回方法

public abstract class Builder {
    /*產品實例*/
    protected Product product = new Product();

    /*抽象方法*/
    public abstract void buildBuyFood();
    public abstract void buildWashFood();
    public abstract void buildFireFood();
    public abstract void buildSaltFood();
    public abstract void buildWaterFood();

    /*返回方法*/
    public Product getProduct(){
        return product;
    }
}

(3)創建一個具體建造者ConcreteBuilder 類,具體建造者類實現了抽象建造者類的抽象接口,構建和步驟等

public class ConcreteBuilder extends Builder {
    @Override
    public void buildBuyFood() {
        System.out.println("去超市購買白菜");
    }

    @Override
    public void buildWashFood() {
        System.out.println("把白菜清洗乾淨");
    }

    @Override
    public void buildFireFood() {
        System.out.println("用火炒菜,做炒白菜");
    }

    @Override
    public void buildSaltFood() {
        System.out.println("用鹽醃菜,做辣白菜");
    }

    @Override
    public void buildWaterFood() {
        System.out.println("用水煮菜,做白菜湯");
    }
}

(4)創建一個指揮者類Director 類

public class Director {
    private Builder builder;

    /*構造方法的方式注入builder對象*/
    public Director(Builder builder){
        this.builder = builder;
    }

    /*set方法注入builder對象*/
    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    /*炒白菜*/
    public Product constructFire() {
        builder.buildBuyFood();
        builder.buildWashFood();
        builder.buildFireFood();
        return builder.getProduct();
    }

    /*醃白菜*/
    public Product constructSalt() {
        builder.buildBuyFood();
        builder.buildWashFood();
        builder.buildSaltFood();
        return builder.getProduct();
    }

    /*白菜湯*/
    public Product constructWater() {
        builder.buildBuyFood();
        builder.buildWashFood();
        builder.buildWaterFood();
        return builder.getProduct();
    }
}

(5)main方法測試類

public class Jzzms {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        /*調用炒白菜*/
        System.out.println("--------炒白菜的做法步驟--------");
        director.constructFire();

        /*調用醃白菜*/
        System.out.println("--------醃白菜的做法步驟--------");
        director.constructSalt();

        /*調用煮白菜*/
        System.out.println("--------白菜湯的做法步驟--------");
        director.constructWater();
    }
}

(6)輸出結果

--------炒白菜的做法步驟--------
去超市購買白菜
把白菜清洗乾淨
用火炒菜,做炒白菜
--------醃白菜的做法步驟--------
去超市購買白菜
把白菜清洗乾淨
用鹽醃菜,做辣白菜
--------白菜湯的做法步驟--------
去超市購買白菜
把白菜清洗乾淨
用水煮菜,做白菜湯

(7)分析

  • 從上面的代碼可以得到,用戶只需要指定需要什麼樣的產品(做什麼菜),而不用去管具體的完成步驟和細節;
  • 建造製作過程由指揮者來控制,建造細節由一個抽象類來控制,對於實現建造細節的具體類來說,不會遺漏某一個步驟。
  • 指揮者針對抽象建造者編程,客戶端只需要知道具體建造者的類型,即可通過指揮者類調用建造者的相關方法,返回一個完整的產品對象。建造者負責控制產品的生成過程,並且隔離了客戶與生產過程。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章