我们已经在第 1 组中讨论了 Pizza 设计问题和解决它的不同天真方法。我们还在第 2 组中引入了装饰器模式。
在本文中,讨论了 Pizza 问题的装饰器模式的设计和实现。强烈建议您先自己尝试一下。
新建类图(点击图片看清楚)
- Pizza充当我们的抽象组件类。
- 有四个具体组件,即PeppyPaneer 、 FarmHouse 、 Margherita 、 ChickenFiesta 。
- ToppingsDecorator是我们的抽象装饰器,而FreshTomato 、 Paneer 、 Jalapeno 、 Barbeque是具体装饰器。
下面是上述设计的Java实现。
// Java program to demonstrate Decorator
// pattern
// Abstract Pizza class (All classes extend
// from this)
abstract class Pizza
{
// it is an abstract pizza
String description = "Unkknown Pizza";
public String getDescription()
{
return description;
}
public abstract int getCost();
}
// The decorator class : It extends Pizza to be
// interchangable with it topings decorator can
// also be implemented as an interface
abstract class ToppingsDecorator extends Pizza
{
public abstract String getDescription();
}
// Concrete pizza classes
class PeppyPaneer extends Pizza
{
public PeppyPaneer() { description = "PeppyPaneer"; }
public int getCost() { return 100; }
}
class FarmHouse extends Pizza
{
public FarmHouse() { description = "FarmHouse"; }
public int getCost() { return 200; }
}
class Margherita extends Pizza
{
public Margherita() { description = "Margherita"; }
public int getCost() { return 100; }
}
class ChickenFiesta extends Pizza
{
public ChickenFiesta() { description = "ChickenFiesta";}
public int getCost() { return 200; }
}
class SimplePizza extends Pizza
{
public SimplePizza() { description = "SimplePizza"; }
public int getCost() { return 50; }
}
// Concrete toppings classes
class FreshTomato extends ToppingsDecorator
{
// we need a reference to obj we are decorating
Pizza pizza;
public FreshTomato(Pizza pizza) { this.pizza = pizza; }
public String getDescription() {
return pizza.getDescription() + ", Fresh Tomato ";
}
public int getCost() { return 40 + pizza.getCost(); }
}
class Barbeque extends ToppingsDecorator
{
Pizza pizza;
public Barbeque(Pizza pizza) { this.pizza = pizza; }
public String getDescription() {
return pizza.getDescription() + ", Barbeque ";
}
public int getCost() { return 90 + pizza.getCost(); }
}
class Paneer extends ToppingsDecorator
{
Pizza pizza;
public Paneer(Pizza pizza) { this.pizza = pizza; }
public String getDescription() {
return pizza.getDescription() + ", Paneer ";
}
public int getCost() { return 70 + pizza.getCost(); }
}
// Other toppings can be coded in a similar way
// Driver class and method
class PizzaStore
{
public static void main(String args[])
{
// create new margherita pizza
Pizza pizza = new Margherita();
System.out.println( pizza.getDescription() +
" Cost :" + pizza.getCost());
// create new FarmHouse pizza
Pizza pizza2 = new FarmHouse();
// decorate it with freshtomato topping
pizza2 = new FreshTomato(pizza2);
//decorate it with paneer topping
pizza2 = new Paneer(pizza2);
System.out.println( pizza2.getDescription() +
" Cost :" + pizza2.getCost());
Pizza pizza3 = new Barbeque(null); //no specific pizza
System.out.println( pizza3.getDescription() + " Cost :" + pizza3.getCost());
}
}
输出:
Margherita Cost :100
FarmHouse, Fresh Tomato , Paneer Cost :310
请注意我们如何在不改变先前测试的代码的情况下添加/删除新的比萨饼和配料,并且配料和比萨饼是分离的。
// CPP program to demonstrate
// Decorator pattern
#include
#include
using namespace std;
// Component
class MilkShake
{
public:
virtual string Serve() = 0;
virtual float price() = 0;
};
// Concrete Component
class BaseMilkShake : public MilkShake
{
public:
string Serve()
{
return "MilkShake";
}
float price()
{
return 30;
}
};
// Decorator
class MilkShakeDecorator: public MilkShake
{
protected:
MilkShake *m_MilkShake;
public:
MilkShakeDecorator(MilkShake *baseMilkShake): m_MilkShake(baseMilkShake){}
string Serve()
{
return m_MilkShake->Serve();
}
float price()
{
return m_MilkShake->price();
}
};
// Concrete Decorator
class MangoMilkShake: public MilkShakeDecorator
{
public:
MangoMilkShake(MilkShake *baseMilkShake): MilkShakeDecorator(baseMilkShake){}
string Serve()
{
return m_MilkShake->Serve() + " decorated with Mango ";
}
float price()
{
return m_MilkShake->price() + 40;
}
};
class VanillaMilkShake: public MilkShakeDecorator
{
public:
VanillaMilkShake(MilkShake *baseMilkShake): MilkShakeDecorator(baseMilkShake){}
string Serve()
{
return m_MilkShake->Serve() + " decorated with Vanilla ";
}
float price()
{
return m_MilkShake->price() + 80;
}
};
int main()
{
MilkShake *baseMilkShake = new BaseMilkShake();
cout << "Basic Milk shake \n";
cout << baseMilkShake -> Serve() << endl;
cout << baseMilkShake -> price() << endl;
MilkShake *decoratedMilkShake = new MangoMilkShake(baseMilkShake);
cout << "Mango decorated Milk shake \n";
cout << decoratedMilkShake -> Serve() << endl;
cout << decoratedMilkShake -> price() << endl;
delete decoratedMilkShake;
decoratedMilkShake = new VanillaMilkShake(baseMilkShake);
cout << "Vanilla decorated Milk shake \n";
cout << decoratedMilkShake -> Serve() << endl;
cout << decoratedMilkShake -> price() << endl;
delete decoratedMilkShake;
delete baseMilkShake;
return 0;
}
输出:
Basic Milk shake
MilkShake
Price of MilkShake : 30
Mango decorated Milk shake
MilkShake decorated with Mango
Price of Mango MilkShake : 70
Vanilla decorated Milk shake
MilkShake decorated with Vanilla
Price of Vanilla MilkShake : 110