Builder Pattern(建造者模式)

建造者模式(Builder Pattern):組裝具有復(fù)雜結(jié)構(gòu)的實(shí)例。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式。

介紹

  • 意圖:將一個(gè)復(fù)雜的構(gòu)建與其表示相分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
  • 主要解決:主要解決在軟件系統(tǒng)中,有時(shí)候面臨著"一個(gè)復(fù)雜對(duì)象"的創(chuàng)建工作,其通常由各個(gè)部分的子對(duì)象用一定的算法構(gòu)成;由于需求的變化,這個(gè)復(fù)雜對(duì)象的各個(gè)部分經(jīng)常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對(duì)穩(wěn)定。
  • 何時(shí)使用:一些基本部件不會(huì)變,而其組合經(jīng)常變化的時(shí)候。
  • 應(yīng)用實(shí)例: 去肯德基,漢堡、可樂(lè)、薯?xiàng)l、炸雞翅等是不變的,而其組合是經(jīng)常變化的,生成出所謂的"套餐"。
  • 優(yōu)點(diǎn):
    1、建造者獨(dú)立,易擴(kuò)展。
    2、便于控制細(xì)節(jié)風(fēng)險(xiǎn)。
  • 缺點(diǎn):
    1、產(chǎn)品必須有共同點(diǎn),范圍有限制。
    2、如內(nèi)部變化復(fù)雜,會(huì)有很多的建造類。
  • 使用場(chǎng)景:
    1、需要生成的對(duì)象具有復(fù)雜的內(nèi)部結(jié)構(gòu)。
    2、需要生成的對(duì)象內(nèi)部屬性本身相互依賴。

注意事項(xiàng):與工廠模式的區(qū)別是:建造者模式更加關(guān)注與零件裝配的順序。

示例

type.ts 定義食物接口和包裝接口

/**
 * 食物接口
 */
export interface Food {
    name(): string;
    packing(): Packing;
    price(): number;
}
/**
 * 包裝接口
 */
export interface Packing {
    pack(): string
}

Wrapper.ts 紙質(zhì)包裝類

import { Packing } from "./type";

export default class Wrapper implements Packing {
    public pack(): string {
        return "Wrapper";
    }
}

Bottle.ts 定義瓶裝類

import { Packing } from "./type";

export default class Bottle implements Packing {
    public pack(): string {
        return "Bottle";
    }
}

Burger.ts 實(shí)現(xiàn)食物接口沒(méi)定義包裝為紙質(zhì)

import { Food, Packing } from "./type";
import Wrapper from "./Wrapper";

export default abstract class Burger implements Food {
    public abstract name(): string;
    public packing(): Packing {
        return new Wrapper();
    }

    public abstract price(): number;
}

ColdDrink.ts 冷飲類實(shí)現(xiàn)食物接口,并指定包裝為瓶裝

import { Food, Packing } from "./type";
import Bottle from "./Bottle";

export default abstract class ColdDrink implements Food {
    public abstract name(): string;
    public packing(): Packing {
        return new Bottle();
    }

    public abstract price(): number;
}

VegBurger.ts 蔬菜漢堡類

import Burger from "./Burger";

export default class VegBurger extends Burger {
    public price(): number {
        return 25;
    }
    public name(): string {
        return "Veg Burger";
    }
}

ChickenBurger.ts 雞肉堡類

import Burger from "./Burger";

export default class ChickenBurger extends Burger {

    public price(): number {
        return 50.5;
    }

    public name(): string {
        return "Chicken Burger";
    }
}

Pepsi.ts 百事飲料類

import ColdDrink from "./ColdDrink";

export default class Pepsi extends ColdDrink {

    public price(): number {
        return 35.0;
    }

    public name(): string {
        return "Pepsi";
    }
}

Coke.ts 可口可樂(lè)類繼承自冷飲

import ColdDrink from "./ColdDrink";

export default class Coke extends ColdDrink {

    public price(): number {
        return 30.0;
    }
    public name(): string {
        return "Coke";
    }
}

Meal.ts 套餐類,里面有食物和總價(jià)

import { Food } from "./type";

export default class Meal {
    private items = new Array<Food>();

    public addItem(item: Food): void {
        this.items.push(item);
    }

    public getCost(): number {
        let cost = 0;
        for (const item of this.items) {
            cost += item.price();
        }
        return cost;
    }

    public showItems(): void {
        for (const item of this.items) {
            console.log(`Food : ${item.name()}, Packing : ${item.packing().pack()}, Price : ${item.price()}`);
        }
    }
}

MealBuilder.ts 創(chuàng)建套餐,有蔬菜和沒(méi)蔬菜的套餐

import Meal from "./Meal";
import VegBurger from "./VegBurger";
import Coke from "./Coke";
import ChickenBurger from "./ChickenBurger";
import Pepsi from "./Pepsi";

export default class MealBuilder {

    public prepareVegMeal(): Meal {
        const meal = new Meal();
        meal.addItem(new VegBurger());
        meal.addItem(new Coke());
        return meal;
    }

    public prepareNonVegMeal(): Meal {
        const meal = new Meal();
        meal.addItem(new ChickenBurger());
        meal.addItem(new Pepsi());
        return meal;
    }
}

index.ts

import MealBuilder from "./MealBuilder";

const mealBuilder = new MealBuilder();

const vegMeal = mealBuilder.prepareVegMeal();
console.log("-----Veg Meal-------");
vegMeal.showItems();
console.log("Total Cost: " + vegMeal.getCost());

const nonVegMeal = mealBuilder.prepareNonVegMeal();
console.log("-----Non-Veg Meal-----");
nonVegMeal.showItems();
console.log("Total Cost: " + nonVegMeal.getCost());

result

-----Veg Meal-------
Food : Veg Burger, Packing : Wrapper, Price : 25
Food : Coke, Packing : Bottle, Price : 30
Total Cost: 55
-----Non-Veg Meal-----
Food : Chicken Burger, Packing : Wrapper, Price : 50.5
Food : Pepsi, Packing : Bottle, Price : 35
Total Cost: 85.5

類圖

角色

  • Builder(建造者)
    Builder角色負(fù)責(zé)定義用于生產(chǎn)實(shí)例的接口,Builder角色中有用于生產(chǎn)實(shí)例的方法
  • ConcreteBuilder(具體的建造者)
    ConcreteBuilder角色時(shí)負(fù)責(zé)實(shí)現(xiàn)Builder角色的接口的類,定義了在生產(chǎn)實(shí)例時(shí)實(shí)際被調(diào)用的犯法,此外,在ConcreteBuilder中還定義了獲取最終生產(chǎn)結(jié)果的方法
  • Director(監(jiān)工)
    Director角色負(fù)責(zé)使用Builder角色的接口來(lái)生產(chǎn)實(shí)例,不依賴于ConcreteBuilder角色。它只調(diào)用在Builder角色中被定義的方法
  • Client(使用者)
    該角色使用了Builder模式。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容