裝飾者模式(decorator pattern)

裝飾者模式:spa

    可以動態地往一個類中添加新的行爲。相比繼承是在編譯時添加行爲,裝飾模式是在運行時添加行爲。code

星巴克咖啡是講述裝飾者模式的一個很好的例子。對象

    假設如今有兩種咖啡:HouseBlend、DarkRoast,同時有兩種調料:Milk、Mocha。那麼此時咱們能夠給顧客提供如下咖啡:blog

HouseBlend、HouseBlendWithMilk、HouseBlendWithMocha、HouseBlendWithMilkandMocha、繼承

DarkRoast、DarkRoastWithMilk、DarkRoastWithMocha、DarkRoastWithMilkandMocha。若是每種搭配都是一個類,那麼隨着咖啡和調料種類的增長,將會出現類爆炸:ip

此時裝飾者模式應運而生,結構圖以下:get

C++實現:string

class Coffee {
public:
    virtual double getCost() = 0;
    virtual string getDescription() = 0;
};

class HouseBlend : public Coffee {
public:
    double getCost() { return 1.24; }
    string getDescription() { return "HouseBlend"; }
};

class DarkRoast : public Coffee {
public:
    double getCost() { return 2.73; }
    string getDescription() { return "DarkRoast"; }
};

class CoffeeDecorator : public Coffee {
private:
    Coffee *decoratedCoffee;
public:
    CoffeeDecorator(Coffee *c): decoratedCoffee(c) {}
    double getCost() { return decoratedCoffee->getCost(); }
    string getDescription() { return decoratedCoffee->getDescription(); }
};

class Milk : public CoffeeDecorator {
public:
    Milk(Coffee *c): CoffeeDecorator(c) {}
    double getCost() { return CoffeeDecorator::getCost() + 0.5; }
    string getDescription() {return CoffeeDecorator::getDescription() + ", Milk"; }
};

class Mocha : public CoffeeDecorator {
public:
    Mocha(Coffee *c): CoffeeDecorator(c) {}
    double getCost() { return CoffeeDecorator::getCost() + 0.7; }
    string getDescription() {return CoffeeDecorator::getDescription() + ", Mocha"; }
};

int main()
{
    Coffee *pc = new HouseBlend;
    cout << "description: " << pc->getDescription() << "  cost: " << pc->getCost() << endl;
    pc = new Milk(pc);
    cout << "description: " << pc->getDescription() << "  cost: " << pc->getCost() << endl;
    pc = new Mocha(pc);
    cout << "description: " << pc->getDescription() << "  cost: " << pc->getCost() << endl;
    delete pc;
}

裝飾者模式的一個特徵是:裝飾者和被裝飾對象具備相同的超類型。it

reference:io

Decorator in C++: Before and after

相關文章
相關標籤/搜索