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