装饰器模式(Decorator Pattern)允许在运行时动态地向对象添加功能,而无需修改其源代码。在该模式中,有一个被装饰的对象(Component),它定义了一些基本的操作。装饰器(Decorator)对象是对这个基本对象的一个包装,可以在不改变其接口的情况下,为其添加新的行为或修改现有的行为。
通过使用装饰器模式,可以避免使用继承带来的静态扩展,而使用对象组合的方式来动态扩展对象的行为。这种方式也可以避免创建大量的子类,从而提高代码的可维护性和灵活性。
装饰器模式的组件包括:抽象组件(Component)、具体组件(ConcreteComponent)、抽象装饰器(Decorator)和具体装饰器(ConcreteDecorator)。
抽象组件(Component)定义了基本的操作,具体组件(ConcreteComponent)实现了基本操作。抽象装饰器(Decorator)也是一个抽象组件,它持有一个被装饰的对象,并定义了一个与抽象组件一样的接口。具体装饰器(ConcreteDecorator)实现了具体的装饰行为,并在其中调用被装饰对象的方法。
装饰器模式的优点在于它可以动态地添加或删除对象的功能,而且具有灵活性和可扩展性。它可以避免使用继承带来的静态扩展,并且能够避免在代码中创建大量的子类。缺点在于,如果有太多的装饰器,代码可能会变得复杂。
1、场景设计
实现场景:调制两杯咖啡。一杯是独立的浓缩咖啡,一杯是深度烘焙咖啡加两层摩卡和一层奶泡。
2、C++实现
#include <iostream>
#include <string>
// 抽象组件
class Beverage {
public:
virtual std::string getDescription() = 0;
virtual double getCost() = 0;
};
// 具体组件:浓缩咖啡
class Espresso : public Beverage {
public:
std::string getDescription() override {
return "Espresso";
}
double getCost() override {
return 1.99;
}
};
// 具体组件:深度烘焙咖啡
class DarkRoast : public Beverage {
public:
std::string getDescription() override {
return "Dark Roast Coffee";
}
double getCost() override {
return 0.99;
}
};
// 抽象装饰器
class CondimentDecorator : public Beverage {
public:
virtual std::string getDescription() = 0;
};
// 具体装饰器:加摩卡且售价加0.2
class Mocha : public CondimentDecorator {
public:
Mocha(Beverage* beverage) {
this->beverage = beverage;
}
std::string getDescription() override {
return beverage->getDescription() + ", Mocha";
}
double getCost() override {
return 0.20 + beverage->getCost();
}
private:
Beverage* beverage;
};
// 具体装饰器:加奶泡且售价加0.1
class Whip : public CondimentDecorator {
public:
Whip(Beverage* beverage) {
this->beverage = beverage;
}
std::string getDescription() override {
return beverage->getDescription() + ", Whip";
}
double getCost() override {
return 0.10 + beverage->getCost();
}
private:
Beverage* beverage;
};
int main() {
Beverage* beverage = new Espresso();
std::cout << beverage->getDescription() << " $" << beverage->getCost() << std::endl;
Beverage* beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
std::cout << beverage2->getDescription() << " $" << beverage2->getCost() << std::endl;
delete beverage;
delete beverage2;
return 0;
}
3、Java实现
DecoratorDemo.java
package structuralpattern.decorator;
// 抽象组件
interface Beverage {
String getDescription();
double getCost();
}
// 具体组件:浓缩咖啡
class Espresso implements Beverage {
@Override
public String getDescription() {
return "Espresso";
}
@Override
public double getCost() {
return 1.99;
}
}
// 具体组件:深度烘焙咖啡
class DarkRoast implements Beverage {
@Override
public String getDescription() {
return "Dark Roast Coffee";
}
@Override
public double getCost() {
return 0.99;
}
}
// 抽象装饰器
abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription();
}
@Override
public double getCost() {
return beverage.getCost();
}
}
// 具体装饰器:加摩卡且售价加0.2
class Mocha extends CondimentDecorator {
Mocha(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double getCost() {
return 0.20 + beverage.getCost();
}
}
// 具体装饰器:加奶泡且售价加0.1
class Whip extends CondimentDecorator {
Whip(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
@Override
public double getCost() {
return 0.10 + beverage.getCost();
}
}
public class DecoratorDemo {
public static void main(String[] args){
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.getCost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.getCost());
}
}