HeadFirst設計模式-裝飾者模式

裝飾者模式:動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

UML:

Java代碼

package c_DecoratorPattern._01_coffe;

/**
 * 飲料
 */
public abstract class Beverage {
    String description = "Unknown Beverage";
    public String getDescription() {
        return description;
    }
    public abstract double cost();
}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

public class DarkRoast extends Beverage {
    
    public DarkRoast() {
        this.description = "Dark Roast Coffee";
    }

    @Override
    public double cost() {
        return 0.99;
    }

}

//--------------------------------------
package c_DecoratorPattern._01_coffe;

/**
 * 濃縮咖啡
 */
public class Espresso extends Beverage {
    
    public Espresso() {
        this.description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }

}

//--------------------------------------
package c_DecoratorPattern._01_coffe;

/**
 * 綜合
 */
public class HouseBlend extends Beverage {
    
    public HouseBlend() {
        this.description = "House Blend coffee";
    }

    @Override
    public double cost() {
        return 0.89;
    }

}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

/**
 * 調料
 *
 */
public abstract class Condiment extends Beverage {

    public abstract String getDescription();
}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

/**
 * 摩卡
 */
public class Mocha extends Condiment {
    
    private Beverage beverage;
    
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return this.beverage.getDescription() + ", Mocha";
    }

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }

}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

/**
 * 豆漿
 * 
 */
public class Soy extends Condiment {

    private Beverage beverage;

    public Soy(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return this.beverage.getDescription() + ", Soy";
    }

    @Override
    public double cost() {
        return .15 + beverage.cost();
    }

}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

/**
 * 奶泡
 *
 */
public class Whip extends Condiment {

    private Beverage beverage;

    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return this.beverage.getDescription() + ", Whip";
    }

    @Override
    public double cost() {
        return .10 + beverage.cost();
    }

}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

public class Milk extends Condiment {

    private Beverage beverage;
    
    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }
    
    @Override
    public String getDescription() {
        return this.beverage.getDescription() + ", Milk";
    }

    @Override
    public double cost() {
        return .10 + beverage.cost();
    }

}
//--------------------------------------
package c_DecoratorPattern._01_coffe;

public class TestCoffee {

    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
        
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
        
        Beverage beverage3 = new HouseBlend();
        beverage3 = new Soy(beverage3);
        beverage3 = new Mocha(beverage3);
        beverage3 = new Whip(beverage3);
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
    }

}
//--------------------------------------
Espresso $1.99
Dark Roast Coffee, Mocha, Mocha, Whip $1.49
House Blend coffee, Soy, Mocha, Whip $1.34
//--------------------------------------
View Code

 

C++代碼

#pragma once
#include <string>
using std::string;

class Beverage
{
public:

    Beverage()
    {
    }

    virtual ~Beverage()
    {
    }

    virtual string getDescription() const
    {
        return description;
    }

    virtual double cost() const = 0;//純虛函數可以有函數體

protected:
    string description = "Unknown Beverage";
};

//--------------------------------------

#pragma once
#include "Beverage.h"
class DarkRoast :
    public Beverage
{
public:

    DarkRoast()
    {
        this->description = "Dark Roast Coffee";
    }

    virtual ~DarkRoast()
    {
    }

    virtual double cost() const
    {
        return 0.99;
    }
};

#pragma once
#include "Beverage.h"
class Condiment :
    public Beverage
{
public:

    Condiment()
    {
    }

    virtual ~Condiment()
    {
    }

    virtual string getDescription() const = 0; //純虛函數可以有函數體
};
//--------------------------------------
#pragma once
#include "Beverage.h"
class Espresso :
    public Beverage
{
public:

    Espresso()
    {
        this->description = "Espresso Coffee";
    }

    virtual ~Espresso()
    {
    }

    virtual double cost() const
    {
        return 1.99;
    }
};


//--------------------------------------
#pragma once
#include "Beverage.h"
class HouseBlend :
    public Beverage
{
public:

    HouseBlend()
    {
        this->description = "House Blend Coffee";
    }

    virtual ~HouseBlend()
    {
    }

    virtual double cost() const
    {
        return 0.89;
    }
};


//--------------------------------------
#pragma once
#include "Condiment.h"
class Mocha :
    public Condiment
{

private:
    Beverage* beverage; 
public:

    Mocha(Beverage* beverage)
    {
        this->beverage = beverage;
    }

    virtual ~Mocha()
    {
    }

    virtual string getDescription() const
    {
        return beverage->getDescription() + ",Mocha";
    }

    virtual double cost() const
    {
        return 0.20 + beverage->cost();
    }

private:
    Mocha(const Mocha& m){

    }
};


//--------------------------------------
#pragma once
#include "Condiment.h"

//奶泡
class Whip :
    public Condiment
{

private:
    Beverage* beverage;
public:

    Whip(Beverage* beverage)
    {
        this->beverage = beverage;
    }

    virtual ~Whip()
    {
    }

    virtual string getDescription() const
    {
        return beverage->getDescription() + ",Whip";
    }

    virtual double cost() const
    {
        return 0.10 + beverage->cost();
    }

};


//--------------------------------------
#pragma once
#include "Condiment.h"
class Soy :
    public Condiment
{

private:
    Beverage* beverage;
public:

    Soy(Beverage* beverage)
    {
        this->beverage = beverage;
    }

    virtual ~Soy()
    {
    }

    virtual string getDescription() const
    {
        return beverage->getDescription() + ",Soy";
    }

    virtual double cost() const
    {
        return 0.15 + beverage->cost();
    }

};


//--------------------------------------
#pragma once
#include "Condiment.h"
class Milk :
    public Condiment
{

private:
    Beverage* beverage;
public:

    Milk(Beverage* beverage)
    {
        this->beverage = beverage;
    }

    virtual ~Milk()
    {
    }

    virtual string getDescription() const
    {
        return beverage->getDescription() + ",Milk";
    }

    virtual double cost() const
    {
        return 0.10 + beverage->cost();
    }

};


//--------------------------------------
#include <iostream>
#include "Condiment.h"
#include "DarkRoast.h"
#include "HouseBlend.h"
#include "Espresso.h"
#include "Mocha.h"
#include "Whip.h"
#include "Soy.h"
using namespace std;

void display(const Beverage& b){
    cout <<"name:" << b.getDescription() << "\ncost:" << b.cost() << endl;
}

void display2(const Beverage* b){
    cout << "name:" << b->getDescription() << "\ncost:" << b->cost() << endl;
}

int main(){
    //濃縮咖啡
    Espresso e;
    display(e);

    //深烘焙 + 2份摩卡 + 1份奶泡
    DarkRoast dr;
    Mocha mo(&dr);
    Mocha mo2(&mo);
    Whip w(&mo2);
    display(w);

    //混合 + 豆漿 + 摩卡 + 奶泡
    HouseBlend hb;
    Soy t1(&hb);
    Mocha t2(&t1);
    Whip t3(&t2);
    Beverage* b = &t3;
    display2(b);
}
/*
name:Espresso Coffee
cost:1.99
name:Dark Roast Coffee,Mocha,Mocha,Whip
cost:1.49
name:House Blend Coffee,Soy,Mocha,Whip
cost:1.34
*/
//--------------------------------------
View Code

 

--------------------

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