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 //--------------------------------------
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 */ //--------------------------------------
--------------------
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。