創建型設計模式之--建造者模式

建造者模式也被稱爲生成器模式,它是創建一個複雜對象的創建型模式,其將構建複雜對象的過程和它的部件解耦,使得構建過程和部件的表示分離開來。

我們接着用工廠模式中的果園舉例,我們的水果店爲了吸引老顧客、以及新顧客辦理會員,推出了各式各樣的促銷活動,例如會員購買蘋果、香蕉、桔子可以減15元;假日促銷活動可以立減10元的活動;如圖,目前我們推出了兩種活動套餐

上面一條流程可以抽象爲如下步驟:首先設定蘋果禮盒價錢-->設置香蕉禮盒價錢-->設置桔子禮盒價錢-->設置折扣價錢,最終我們拿到了水果套餐的結算價。抽象步驟如下:

建造者模式定義:將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

在建造者模式中有如下角色。
• Director:導演類,負責安排已有模塊的順序,然後通知Builder開始建造。
• Builder:抽象Builder類,規範產品的組建,一般由子類實現。
• ConcreteBulider:具體建造者,實現抽象 Builder 類定義的所有方法,並且返回一個組建好的對象。
• Product:產品類。

對應的類圖:

  • 概念中的導演類,就是我們建造出來的對象的使用者,例如本例中收銀臺就是一步一步給各個水果定價的收銀員,也就是建造者模式建造出來的對象的使用者;
  • builder接口,就是我們四個固定的定價步驟;
  • HolidayBuilder、OldCustomBuilder就是上面builder的具體實現類;
  • FruitMeal就是我們建造者模式最終建造出來的複雜的對象。

對應的實現代碼:

建造者需要的複雜建造步驟,最終需要返回這個複雜的套餐對象:

//創建一個MealBuilder類,實際的builder類負責創建套餐Meal對象。
public interface Builder {//也是工廠

    void buildApple(int price);//設置蘋果
    void buildBanana(int price);//設置香蕉
    void buildOrange(int price);//設置桔子

    FruitMeal getFruitMeal();//返回創建的套餐
}

兩種對應的建造師,就是這個複雜步驟的實現對象:

假期水果套餐建造者:

/**
 * 假期水果套餐
 */
public class HolidayBuilder implements Builder {
    private FruitMeal fruitMeal = new FruitMeal();

    @Override
    public void buildApple(int price) {
        Apple apple = new Apple();
        apple.setPrice(price);
        fruitMeal.setApple(apple);
    }

    @Override
    public void buildBanana(int price) {
        Banana fruit = new Banana();
        fruit.setPrice(price);
        fruitMeal.setBanana(fruit);
    }

    @Override
    public void buildOrange(int price) {
        Orange fruit = new Orange("Peter",80);
        fruit.setPrice(price);
        fruitMeal.setOrange(fruit);
    }

    @Override
    public FruitMeal getFruitMeal() {
        fruitMeal.setDiscount(15);//折扣價格對一個套餐來,是固定的
        fruitMeal.init();
        return fruitMeal;
    }
}

老會員水果套餐建造者:

/**
 * 老會員水果套餐
 */
public class OldCustomerBuilder implements Builder {
    private FruitMeal fruitMeal = new FruitMeal();

    @Override
    public void buildApple(int price) {
        Apple apple = new Apple();
        apple.setPrice(price);
        fruitMeal.setApple(apple);
    }

    @Override
    public void buildBanana(int price) {
        Banana fruit = new Banana();
        fruit.setPrice(price);
        fruitMeal.setBanana(fruit);
    }

    @Override
    public void buildOrange(int price) {
        Orange fruit = new Orange("Peter",80);
        fruit.setPrice(price);
        fruitMeal.setOrange(fruit);
    }

    @Override
    public FruitMeal getFruitMeal() {
        fruitMeal.setDiscount(10);
        fruitMeal.init();
        return fruitMeal;
    }
}

最終需要建造的水果套餐類:

//創建一個水果套餐Meal類
public class FruitMeal {

    private Apple apple;//蘋果--價格
    private Banana banana;//香蕉價格
    private Orange orange;    //桔子價格
    private int discount;//折扣價

    private int totalPrice;//套餐總價

    public void setDiscount(int discount) {
        this.discount = discount;
    }

    public void setApple(Apple apple) {
        this.apple = apple;
    }

    public void setBanana(Banana banana) {
        this.banana = banana;
    }

    public void setOrange(Orange orange) {
        this.orange = orange;
    }

    public int cost(){
        return this.totalPrice;
    }

    public void init() {
        if (null != apple){
            totalPrice += apple.price();
        }
        if (null != orange){
            totalPrice += orange.price();
        }
        if (null != banana){
            totalPrice += banana.price();
        }
        if (totalPrice > 0){
            totalPrice -= discount;
        }
    }

    public void showItems() {
        System.out.println("totalPrice:" + totalPrice);
    }
}

導演,建造類的使用者:

public class FruitMealController {//收銀臺---導演類

    public void construct() {
//        Builder builder = new HolidayBuilder();
        Builder builder = new OldCustomerBuilder();//spring注入方法,

        //以下代碼模板,輕易是不變的
        builder.buildApple(120);//創建蘋果設置價格
        builder.buildBanana(80);//創建香蕉設置香蕉價格
        builder.buildOrange(50);//創建桔子設置價格

        FruitMeal fruitMeal = builder.getFruitMeal();


        int cost = fruitMeal.cost();
        System.out.println("本套件花費:"+cost);
    }

    public static void main(String[] args) {
        new FruitMealController().construct();
    }

}

 

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