首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

大話設計模式學習筆記:裝飾器模式 C++ 實戰(飲料加料案例)

     編輯:關於C語言

模式定義與 UML 結構

裝飾器模式:動態地給對象添加額外職責,靈活性優於繼承。——《大話設計模式》P48

四大角色:

  1. Component(抽象構件):定義對象接口
  2. ConcreteComponent(具體構件):被裝飾的核心對象
  3. Decorator(抽象裝飾類):繼承 Component,持有 Component*,轉發請求
  4. ConcreteDecorator(具體裝飾類):具體添加行為/狀態

通用框架代碼骨架

// Component
class Component { public: virtual void Operation() = 0; };

// ConcreteComponent
class ConcreteComponent : public Component {
public: void Operation() override { /* 核心業務 */ }
};

// Decorator
class Decorator : public Component {
public:
    void SetComponent(Component* pc) { component = pc; }
    void Operation() override { if (component) component->Operation(); }
protected: Component* component;
};

// ConcreteDecoratorA:添加狀態
class ConcreteDecoratorA : public Decorator {
public: void Operation() override { Decorator::Operation(); cout << addedState; }
private: string addedState;
};

// ConcreteDecoratorB:添加行為
class ConcreteDecoratorB : public Decorator {
public: void Operation() override { Decorator::Operation(); AddedBehavior(); }
private: void AddedBehavior() { /* 額外邏輯 */ }
};

// Client 組裝鏈
int main() {
    ConcreteComponent* pc = new ConcreteComponent();
    ConcreteDecoratorA* pda = new ConcreteDecoratorA();
    ConcreteDecoratorB* pdb = new ConcreteDecoratorB();
    pda->SetComponent(pc);
    pdb->SetComponent(pda); // 裝飾鏈:pdb -> pda -> pc
    pdb->Operation();
}

實戰案例:飲料加料計價系統

1. 抽象飲料基類

class Beverage {
public:
    Beverage(string n, double c) : name(n), cost(c) {}
    virtual void show() { cout << name; }
    virtual double GetCost() { return cost; }
protected: string name; double cost;
};

// 具體飲料
class Coffee : public Beverage { public: Coffee() : Beverage("咖啡", 5) {} };
class MilkTea : public Beverage { public: MilkTea() : Beverage("奶茶", 6) {} };

2. 抽象裝飾類(輔料基類)

class Decorator : public Beverage {
public:
    void SetComponent(shared_ptr b) { beverage = b; }
    void show() override { if (beverage) beverage->show(); }
    double GetCost() override { return beverage ? beverage->GetCost() : 0; }
protected: shared_ptr beverage; // 使用智能指針管理生命週期
};

3. 具體輔料裝飾類

class MilkFoam : public Decorator { // 奶泡 +1 元
public:
    void show() override { Decorator::show(); cout << " + 奶泡"; }
    double GetCost() override { return Decorator::GetCost() + 1; }
};

class Chocolate : public Decorator { // 巧克力 +2 元
public:
    void show() override { Decorator::show(); cout << " + 巧克力"; }
    double GetCost() override { return Decorator::GetCost() + 2; }
};

class Sugar : public Decorator { // 方糖 +1.5 元
public:
    void show() override { Decorator::show(); cout << " + 方糖"; }
    double GetCost() override { return Decorator::GetCost() + 1.5; }
};

4. 客戶端組裝與輸出

int main() {
    // 咖啡 + 方糖
    auto coffee = make_shared();
    auto sugar = make_shared();
    sugar->SetComponent(coffee);
    sugar->show(); cout << "\n總價格:" << sugar->GetCost() << endl;

    // 奶茶 + 奶泡 + 巧克力
    auto tea = make_shared();
    auto foam = make_shared();
    auto choc = make_shared();
    foam->SetComponent(tea);
    choc->SetComponent(foam); // 鏈式裝飾
    choc->show(); cout << "\n總價格:" << choc->GetCost() << endl;
}

運行結果

我要咖啡加方糖
咖啡 + 方糖
總價格: 6.5
我要奶茶,加奶泡和巧克力
奶茶 + 奶泡 + 巧克力
總價格: 9

模式優勢總結

  • 符合開放-封閉原則:擴展功能無需修改原類
  • 避免類爆炸:繼承需為每種組合建子類,裝飾器靈活組合
  • 支持運行時動態組合:可任意嵌套、順序調整
  • 單一職責:每個裝飾類只關注一項增量功能

本文轉載自 “加和文的世界” 博客,原文地址:https://xuyjun.blog.51cto.com/7470650/1304165

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved