目錄
一、設計原則
開放-關閉原則:類已更改對擴展開放,對修改關閉。
二、認識裝飾者設計模式
三、以裝飾者構造飲料的訂單
四、裝飾者模式框架
五、本文的類圖
代碼設計
價格表
--咖啡飲料價格--
HouseBlend 綜合 0.89
DarkRoast 深焙 0.99
Decat 低咖啡因 1.05
Espresso 濃縮 1.99
--調料價格--
Milk 牛奶 0.10
Mocha 摩卡 0.2
Soy 豆漿 0.15
Whip 奶泡 0.10
六、接口類
6.1飲料接口類
CBeverage.h
#pragma once
//飲料抽象類
class CBeverage
{
public:
CBeverage(void);
virtual ~CBeverage(void);
void Init();
public:
virtual double cost() = 0;
virtual CString GetDescription() const;
protected:
CString m_strDescription;
};
CBeverage.cpp
#include "stdafx.h"
#include "Beverage.h"
CBeverage::CBeverage(void)
{
Init();
}
CBeverage::~CBeverage(void)
{
}
void CBeverage::Init()
{
m_strDescription = _T("Unknow Beverage");
}
CString CBeverage::GetDescription() const
{
return m_strDescription;
}
6.2調料接口類
CCondimentDecorator .h
#pragma once
#include "beverage.h"
//裝飾者類
//調料抽象類
class CCondimentDecorator : public CBeverage
{
public:
CCondimentDecorator(void);
virtual ~CCondimentDecorator(void);
public:
virtual CString GetDescription() const = 0;
};
CCondimentDecorator,cpp
#include "stdafx.h"
#include "CondimentDecorator.h"
CCondimentDecorator::CCondimentDecorator(void)
{
}
CCondimentDecorator::~CCondimentDecorator(void)
{
}
七、寫飲料的代碼
7.1 濃縮咖啡飲料
CEspresso .h
#pragma once
#include "beverage.h"
//濃縮咖啡飲料
class CEspresso : public CBeverage
{
public:
CEspresso(void);
virtual ~CEspresso(void);
public:
virtual double cost();
};
CEspresso .cpp
#include "stdafx.h"
#include "Espresso.h"
CEspresso::CEspresso(void)
{
m_strDescription = _T("Espreso濃縮咖啡");
}
CEspresso::~CEspresso(void)
{
}
double CEspresso::cost()
{
return 1.99; //濃縮咖啡調料的價格
}
7.2 深焙咖啡
CDarkRoast .h
#pragma once
#include "beverage.h"
//深焙咖啡
class CDarkRoast :
public CBeverage
{
public:
CDarkRoast(void);
virtual ~CDarkRoast(void);
public:
virtual double cost();
};
CDarkRoast .cpp
#include "stdafx.h"
#include "DarkRoast.h"
CDarkRoast::CDarkRoast(void)
{
m_strDescription = _T("DarkRoast深焙咖啡");
}
CDarkRoast::~CDarkRoast(void)
{
}
double CDarkRoast::cost()
{
return 0.99;
}
7.3綜合咖啡飲料
CHouseBlend .h
#pragma once
#include "beverage.h"
//綜合 咖啡飲料
class CHouseBlend :
public CBeverage
{
public:
CHouseBlend(void);
virtual ~CHouseBlend(void);
virtual double cost();
};
CHouseBlend .cpp
#include "stdafx.h"
#include "HouseBlend.h"
CHouseBlend::CHouseBlend(void)
{
m_strDescription = _T("HouseBlend綜合咖啡飲料");
}
CHouseBlend::~CHouseBlend(void)
{
}
double CHouseBlend::cost()
{
return 0.89; //綜合 咖啡飲料價格
}
7.4咖啡因飲料
CDecat.h
#pragma once
#include "beverage.h"
//低咖啡因飲料
class CDecat :
public CBeverage
{
public:
CDecat(void);
virtual ~CDecat(void);
public:
virtual double cost();
};
CDecat.cpp
#include "stdafx.h"
#include "Decat.h"
CDecat::CDecat(void)
{
m_strDescription = _T("Decat低咖啡因飲料");
}
CDecat::~CDecat(void)
{
}
double CDecat::cost()
{
return 1.05;
}
八、寫調料的代碼
8.1摩卡調料
CMocha .h
#pragma once
#include "condimentdecorator.h"
class CBeverage;
class CMocha :
public CCondimentDecorator
{
public:
CMocha(CBeverage* pBeverage);
virtual ~CMocha(void);
public:
virtual CString GetDescription() const;
virtual double cost();
private:
CBeverage* m_pBeverage;
};
CMocha .cpp
#include "stdafx.h"
#include "Mocha.h"
#include "Beverage.h"
//調料-摩卡
CMocha::CMocha(CBeverage* pBeverage)
{
m_pBeverage = pBeverage;
}
CMocha::~CMocha(void)
{
}
CString CMocha::GetDescription() const
{
return m_pBeverage->GetDescription() + _T(", Mocha");
}
double CMocha::cost()
{
return 0.2 + m_pBeverage->cost(); //0.2爲摩卡調料的價格
}
8.2 奶泡調料
Whip .h
#pragma once
#include "condimentdecorator.h"
class CBeverage;
//奶泡調料
class CWhip :
public CCondimentDecorator
{
public:
CWhip(CBeverage* pBeverage);
virtual ~CWhip(void);
public:
virtual CString GetDescription() const;
virtual double cost();
private:
CBeverage* m_pBeverage;
};
Whip .cpp
#include "stdafx.h"
#include "Whip.h"
CWhip::CWhip(CBeverage* pBeverage)
{
m_pBeverage = pBeverage;
}
CWhip::~CWhip(void)
{
}
CString CWhip::GetDescription() const
{
return m_pBeverage->GetDescription() + _T(", Mocha");
}
double CWhip::cost()
{
return 0.1 + m_pBeverage->cost(); //0.1爲奶泡調料的價格
}
8.3 豆漿調料
Soy.h
#pragma once
#include "condimentdecorator.h"
class CBeverage;
//豆漿調料
class CSoy :
public CCondimentDecorator
{
public:
CSoy(CBeverage* pBeverage);
virtual ~CSoy(void);
public:
virtual CString GetDescription() const;
virtual double cost();
private:
CBeverage* m_pBeverage;
};
Soy.cpp
#include "stdafx.h"
#include "Soy.h"
CSoy::CSoy(CBeverage* pBeverage)
{
m_pBeverage = pBeverage;
}
CSoy::~CSoy(void)
{
}
CString CSoy::GetDescription() const
{
return m_pBeverage->GetDescription() + _T(", Mocha");
}
double CSoy::cost()
{
return 0.15 + m_pBeverage->cost(); //0.15爲豆漿調料的價格
}
8.4 牛奶調料
Milk.h
#pragma once
#include "condimentdecorator.h"
class CBeverage;
//牛奶調料
class CMilk :
public CCondimentDecorator
{
public:
CMilk(CBeverage* pBeverage);
virtual ~CMilk(void);
public:
virtual CString GetDescription() const;
virtual double cost();
private:
CBeverage* m_pBeverage;
};
Milk.cpp
#include "stdafx.h"
#include "Milk.h"
CMilk::CMilk(CBeverage* pBeverage)
{
m_pBeverage = pBeverage;
}
CMilk::~CMilk(void)
{
}
CString CMilk::GetDescription() const
{
return m_pBeverage->GetDescription() + _T(", Mocha");
}
double CMilk::cost()
{
return 0.1 + m_pBeverage->cost(); //0.1爲牛奶調料的價格
}
九、測試代碼
StartbuzzCoffee.h
#pragma once
class CStartbuzzCoffee
{
public:
CStartbuzzCoffee(void);
~CStartbuzzCoffee(void);
public:
void Main();
};
StartbuzzCoffee.cpp
#include "stdafx.h"
#include "StartbuzzCoffee.h"
#include "Beverage.h"
#include "Espresso.h"
#include "DarkRoast.h"
#include "Mocha.h"
#include "Whip.h"
#include "HouseBlend.h"
#include "Soy.h"
CStartbuzzCoffee::CStartbuzzCoffee(void)
{
}
CStartbuzzCoffee::~CStartbuzzCoffee(void)
{
}
void CStartbuzzCoffee::Main()
{
//訂一杯CEspresso(濃縮咖啡)飲料,不需要調料
CBeverage* m_pBeverage = new CEspresso;
CString strCost;
CString strResult;
strCost.Format(_T("%.2f"), m_pBeverage->cost());
strResult = m_pBeverage->GetDescription() + _T(" $") + strCost; //打印出它的描述與價格
AfxMessageBox(strResult, MB_OK);
//訂一杯 CDarkRoast深焙咖啡 飲料
CBeverage* m_pBeverage2 = new CDarkRoast; //深焙咖啡 飲料 0.99$
m_pBeverage2 = new CMocha(m_pBeverage2); //添加調料摩卡裝飾 0.2$
m_pBeverage2 = new CMocha(m_pBeverage2); //添加調料摩卡裝飾 0.2$
m_pBeverage2 = new CWhip(m_pBeverage2); //添加調料奶泡裝飾 0.1$
strCost.Format(_T("%.2f"), m_pBeverage2->cost()); //=1.49$
strResult = m_pBeverage2->GetDescription() + _T(" $") + strCost; //打印出它的描述與價格
AfxMessageBox(strResult, MB_OK);
//訂一杯 CHouseBlend綜合咖啡 飲料
CBeverage* m_pBeverage3 = new CHouseBlend; //綜合咖啡 飲料 0.89$
m_pBeverage3 = new CSoy(m_pBeverage3); //添加調料豆漿裝飾 0.15$
m_pBeverage3 = new CMocha(m_pBeverage3); //添加調料摩卡裝飾 0.2$
m_pBeverage3 = new CWhip(m_pBeverage3); //添加調料奶泡裝飾 0.1$
strCost.Format(_T("%.2f"), m_pBeverage3->cost()); //=1.34$
strResult = m_pBeverage3->GetDescription() + _T(" $") + strCost; //打印出它的描述與價格
AfxMessageBox(strResult, MB_OK);
delete m_pBeverage;
delete m_pBeverage2;
delete m_pBeverage3;
}
/*
--咖啡飲料價格--
HouseBlend 綜合 0.89
DarkRoast 深焙 0.99
Decat 低咖啡因 1.05
Espresso 濃縮 1.99
--調料價格--
Milk 牛奶 0.10
Mocha 摩卡 0.2
Soy 豆漿 0.15
Whip 奶泡 0.10
*/
十、項目完整代碼
https://github.com/mc-liyanliang/Design-patterns/tree/master/DecoratorPattern
十二、參考資料
《Head First設計模式》