石家庄市栾城区建设局网站,app网站的电话是什么,做国外百科知识网站,wordpress 图表插件装饰模式#xff08;Decorator Pattern#xff09;是一种结构型设计模式#xff0c;它允许在运行时动态地给一个对象添加额外的行为。
描述
装饰模式通过创建一个包装器#xff08;Wrapper#xff09;来包裹原始对象#xff0c;并在原始对象的行为前后添加额外的功能。…装饰模式Decorator Pattern是一种结构型设计模式它允许在运行时动态地给一个对象添加额外的行为。
描述
装饰模式通过创建一个包装器Wrapper来包裹原始对象并在原始对象的行为前后添加额外的功能。通过这种方式可以实现在不改变原始对象结构的情况下动态地给对象添加新的功能。
原理
装饰模式的核心思想是使用继承和组合。创建一个装饰器类它继承自原始对象所属的抽象类或接口并且内部持有一个原始对象的引用。装饰器类通过重写原始对象的方法并在方法的前后添加额外的行为逻辑。
类图 其中的各个类的作用如下 抽象组件(Component): 可以是接口或者抽象类它定义了具体类以及装饰器所拥有的方法。 具体组件(ComponentA, ComponentB):具体的组件实现或者继承自抽象组件。可以理解成上述场景中已存在的类。 抽象装饰器(Decorator):通常为抽象类持有一个被装饰的对象定义了具体装饰器的方法。此类非必须也可以没有具体装饰器也可直接继承或者实现抽象组件。 具体装饰器(DecoratorX, DecoratorY):具体的装饰器继承自抽象装饰器(也可直接继承自抽象组件)扩展了抽象组件的某些功能。 示例
假设有一个咖啡店咖啡有不同种类如浓缩咖啡、美式咖啡和不同口味的添加物如牛奶、糖。希望能够动态地给咖啡添加不同的口味而不需要修改咖啡类的代码。
首先定义一个咖啡的抽象类Coffee其中包含一个获取描述的方法getDescription和获取价格的方法getPrice。 然后创建具体的咖啡类Espresso、Americano它们各自实现了抽象类的方法。 接下来创建一个装饰器类CoffeeDecorator它也继承自咖啡的抽象类并持有一个咖啡对象的引用。 装饰器类可以通过重写抽象类的方法在方法的前后添加额外的行为。
C示例代码如下
// 咖啡抽象类
class Coffee {
public:virtual string getDescription() 0;virtual double getPrice() 0;
// 浓缩咖啡
class Espresso : public Coffee {
public:string getDescription() override {return Espresso;}double getPrice() override {return 1.99;}
};// 美式咖啡
class Americano : public Coffee {
public:string getDescription() override {return Americano;}double getPrice() override {return 2.39;}
};// 咖啡装饰器类
class CoffeeDecorator : public Coffee {
protected:Coffee* coffee;public:CoffeeDecorator(Coffee* coffee) : coffee(coffee) {}string getDescription() override {return coffee-getDescription();}double getPrice() override {return coffee-getPrice();}
};// 牛奶装饰器
class MilkDecorator : public CoffeeDecorator {
public:MilkDecorator(Coffee* coffee) : CoffeeDecorator(coffee) {}string getDescription() override {return coffee-getDescription() , Milk;}double getPrice() override {return coffee-getPrice() 0.5;}
};// 糖装饰器
class SugarDecorator : public CoffeeDecorator {
public:SugarDecorator(Coffee* coffee) : CoffeeDecorator(coffee) {}string getDescription() override {return coffee-getDescription() , Sugar;}double getPrice() override {return coffee-getPrice() 0.3;}
};// 使用示例
int main() {Coffee* espresso new Espresso();cout Description: espresso-getDescription() endl;cout Price: $ espresso-getPrice() endl;Coffee* espressoWithMilk new MilkDecorator(espresso);cout Description: espressoWithMilk-getDescription() endl;cout Price: $ espressoWithMilk-getPrice() endl;delete espresso;espresso 0;delete espressoWithMilk;espressoWithMilk 0;return 0;
}输出结果
Description: Espresso
Price: $1.99
Description: Espresso, Milk
Price: $2.49
首先输出浓缩咖啡Espresso的描述为Espresso价格为$1.99。
然后输出牛奶装饰器MilkDecorator装饰后的浓缩咖啡的描述为Espresso, Milk价格为$2.49。解释
在上述示例中定义了咖啡的抽象类Coffee并创建了具体的浓缩咖啡类Espresso和美式咖啡类Americano。 然后创建了一个咖啡装饰器类CoffeeDecorator它继承自咖啡的抽象类并持有一个咖啡对象的引用。 进一步创建了具体的装饰器类如牛奶装饰器MilkDecorator和糖装饰器SugarDecorator它们分别继承自咖啡装饰器类。
在示例中首先创建了一个浓缩咖啡对象并输出其描述和价格。 然后用牛奶装饰器MilkDecorator装饰该浓缩咖啡对象再次输出描述和价格。 可以看到装饰器类在不改变原始咖啡对象的情况下给其添加了额外的行为。
结论
装饰模式通过包装原始对象在不改变其结构的前提下动态地给对象添加额外的功能。这样可以实现代码的易扩展性和灵活性。
应用场景
装饰模式适用于以下情况
当需要给一个对象动态地添加额外的行为时当需要在不改变对象结构的情况下对对象的某些行为进行扩展当不适合使用继承来扩展对象功能时。
装饰模式可以应用于各种场景如日志记录、权限验证、性能监控等。它可以灵活地给对象添加多个装饰器实现各种组合效果且与原始对象无关。