1. 程式人生 > >7,建造者模式-麥當勞套餐

7,建造者模式-麥當勞套餐

一,前言

開始我們按照由易到難順序進入,現在需要按照設計模式的分類進行了
建立型模式包含:工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式
前篇完成了工廠模式專題了,包括簡單工程,工廠方法模式,抽象工廠模式
下面兩篇我們開始建造者模式和原型模式,這樣就完成了建立型模式這一類的學習

二,建造者模式

建造者模式:將一個複雜的物件的構建和它的表示分離,使得同樣的構建過程可以建立不同的表示

我們以一個麥當勞套餐的例子來說明建造者模式
麥辣雞腿堡套餐:麥辣雞腿漢堡+薯條+可樂
板燒雞腿堡套餐:板燒雞腿漢堡+土豆泥+熱橙汁(板燒雞腿漢堡貌似不是這個組合...)

分析相同點和不同點
相同點:套餐產品型別組合都是漢堡+小吃+飲料
不同點:套餐具體產品不同

按照建造者模式的來實現建立套餐的過程:
建立建造者介面(抽象類)規定產品組成(組裝步驟):主食+小吃+飲料
實現建造者介面的具體抽象類:麥辣雞腿堡套餐,板燒雞腿堡套餐

三,建造者模式的程式碼實現

程式碼結構

1,套餐類:規定包含主食+小吃+飲料的套餐型別

package com.brave.food.builder.food;

/**
 * 套餐類
 *  規定了套餐組成部分:主食+小吃+飲料
 * 
 * @author Brave
 *
 */
public class Combo {

    private String comboName;               // 套餐名稱
    private PrincipalFood principalFood;    // 主食
    private Snack snack;                    // 小吃
private Drink drink; // 飲料 public String getComboName() { return comboName; } public void setComboName(String comboName) { this.comboName = comboName; } public PrincipalFood getPrincipalFood() { return principalFood; } public
void setPrincipalFood(PrincipalFood principalFood) { this.principalFood = principalFood; } public Snack getSnack() { return snack; } public void setSnack(Snack snack) { this.snack = snack; } public Drink getDrink() { return drink; } public void setDrink(Drink drink) { this.drink = drink; } public String show() { return "套餐名稱:" + comboName + ",包含: 主食-" + principalFood.getName() + ", 小吃-" + snack.getName() + ", 飲料-" + drink.getName(); } }

2,建立抽象建造者,規定產品的組成或組裝步驟

package com.brave.food.builder;

import com.brave.food.builder.food.Combo;

/**
 * Builder建造者抽象類
 *  規定了產品的建造有哪些步驟和方法,但不規定順序
 * 
 *  建造者模式:將一個複雜的物件的構建和它的表示分離,使得同樣的構建過程可以建立不同的表示
 * 
 * @author Brave
 *
 */
public abstract class Builder {

    public abstract void buildComboName();
    public abstract void buildPrincipalFood();
    public abstract void buildSnack();
    public abstract void buildDrink();

    public abstract Combo getCombo();

}

3,繼承抽象建造者,建立具體建造者

package com.brave.food.builder;

import com.brave.food.builder.food.Combo;
import com.brave.food.builder.food.Drink;
import com.brave.food.builder.food.PrincipalFood;
import com.brave.food.builder.food.Snack;

/**
 * 麥辣雞腿漢堡套餐建造者(具體Builder類)
 *  對套餐的各個步驟確定具體產品
 * 
 * @author Brave
 *
 */
public class ComboBuilderA extends Builder {

    private Combo product = new Combo();

    @Override
    public void buildComboName() {
        product.setComboName("麥辣雞腿堡套餐");
    }

    @Override
    public void buildPrincipalFood() {
        PrincipalFood principalFood = new PrincipalFood();
        principalFood.setName("麥辣雞腿堡");
        product.setPrincipalFood(principalFood);
    }

    @Override
    public void buildSnack() {
        Snack snack = new Snack();
        snack.setName("薯條");
        product.setSnack(snack);
    }

    @Override
    public void buildDrink() {
        Drink drink = new Drink();
        drink.setName("可口可樂");
        product.setDrink(drink);
    }

    @Override
    public Combo getCombo() {
        return product;
    }

}
package com.brave.food.builder;

import com.brave.food.builder.food.Combo;
import com.brave.food.builder.food.Drink;
import com.brave.food.builder.food.PrincipalFood;
import com.brave.food.builder.food.Snack;

/**
 * 板燒雞腿漢堡套餐建造者(具體Builder類)
 *  對套餐的各個步驟確定具體產品
 * 
 * @author Brave
 *
 */
public class ComboBuilderB extends Builder {

    private Combo product = new Combo();

    @Override
    public void buildComboName() {
        product.setComboName("板燒雞腿堡套餐");
    }

    @Override
    public void buildPrincipalFood() {
        PrincipalFood principalFood = new PrincipalFood();
        principalFood.setName("板燒雞腿堡");
        product.setPrincipalFood(principalFood);
    }

    @Override
    public void buildSnack() {
        Snack snack = new Snack();
        snack.setName("土豆泥");
        product.setSnack(snack);
    }

    @Override
    public void buildDrink() {
        Drink drink = new Drink();
        drink.setName("熱橙汁");
        product.setDrink(drink);
    }

    @Override
    public Combo getCombo() {
        return product;
    }

}

4,建立指揮者類:指揮產品的建立步驟

package com.brave.food.builder;

/**
 * 指揮者類
 *  保證了裝配步驟的完整性和正確性
 *  隔離了客戶端和具體步驟的依賴,將一個複雜物件的構建和製作過程與這個物件的表示分離
 *  
 * @author Brave
 *
 */
public class Director {

    public void ConstructBuild(Builder builder){

        builder.buildComboName();
        builder.buildPrincipalFood();
        builder.buildSnack();
        builder.buildDrink();

    }
}

5,測試類

package com.brave.food.builder;

import com.brave.food.builder.food.Combo;

public class Client {

    public static void main(String[] args) {

        Director director = new Director();
        Builder builderA = new ComboBuilderA();
        Builder builderB = new ComboBuilderB();

        director.ConstructBuild(builderA);
        Combo comboA = builderA.getCombo();
        System.out.println(comboA.show());

        director.ConstructBuild(builderB);
        Combo comboB = builderB.getCombo();
        System.out.println(comboB.show());

    }

}

列印輸出:

套餐名稱:麥辣雞腿堡套餐,包含: 主食-麥辣雞腿堡, 小吃-薯條, 飲料-可口可樂
套餐名稱:板燒雞腿堡套餐,包含: 主食-板燒雞腿堡, 小吃-土豆泥, 飲料-熱橙汁

四,建造者模式分析

建造者模式屬於建立型模式
建造者模式的核心在於,抽象建造者和指揮者這兩個類

抽象建造者(Builder)規定了產品的建立步驟
指揮者(Director)確保了產品組裝順序和步驟的完整性

建造者模式隱藏了產品的組裝過程
客戶端建立產品時,只需傳入指揮者對應的建造者類,即可完成物件建立
客戶端不需要知道產品的建立過程,更不需要知道建立產品需要依賴的其他元件

依賴倒置:依賴於抽象,不依賴具體
只需要指定建立的型別就可以得到對應的物件,而具體的建造過程和細節被Builder和Director隱藏
開放-封閉原則:
指揮者類是針對抽象建造者進行操作的,使用不同的具體建造者就可以得到不同的產品物件

五,建造者模式與工廠模式的比較

工廠模式和建造者模式的相同點:
    都是建立型模式,最終目的都是得到一個物件
    兩者都將物件的建立過程與客戶端隔離
工廠模式和建造者模式的不同點:
    1,側重點不同:
        工廠模式側重與將物件的例項化延遲到子類進行
        建造者側重於保持物件建造過程的穩定性
    2,建立物件的表象不同:
        工廠模式建立相同表象的物件(客戶端向工廠要指定型別的產品)
        建造者模式建立多種表象的物件(傳入相同型別[不同建造者],得到不同產品)