设计模式——装饰器模式
- 设计模式分为创建型、结构型、行为型三大类。
- 创建型设计模式主要解决“对象的创建”问题
- 比较常用的有单例模式和工厂模式,相关链接如下:
- 设计模式——单例模式
- 设计模式——工厂模式
- 结构型设计模式主要解决“类或对象的组合”问题
- 比较常用的有代理模式,装饰器模式,相关链接如下:
- 设计模式——代理模式
- 设计模式——装饰器模式
- 行为型设计模式主要解决的就是“类或对象之间的交互”问题
- 比较常用的有观察者模式,策略模式,模板模式
- 设计模式——观察者模式
- 设计模式——策略模式
- 设计模式——模板模式
目录
- 模式定义和使用场景
- 模式结构
- 装饰器模式优点?
- 装饰器模式缺点?
- 装饰器模式代码实现
1. 模式定义和使用场景
- 装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。
- 主要的作用是在不改变原始对象的基础上,添加增强功能。
- 使用场景:比如有一个披萨类,可以在披萨类的基础上增加番茄披萨类和芝士披萨类。
2. 模式结构
- 装饰模式包含如下角色:
a. Component: 抽象构件
b. ConcreteComponent: 具体构件
c. Decorator: 抽象装饰类
d. ConcreteDecorator: 具体装饰类
3. 装饰器模式优点?
- 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
- 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
- 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
4. 装饰器模式缺点?
- 使用装饰模式会多许多装饰类,增加系统的复杂度,加大学习与理解的难度。
- 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难。
5. 装饰器模式代码实现
1. C++代码实现
#include <iostream>
#include <vector>
using namespace std;
class Component {
public:
Component() = default;
virtual ~Component() = default;
virtual void operation() = 0;
};
class ConcreteComponent : public Component {
public:
ConcreteComponent() = default;
virtual ~ConcreteComponent() = default;
void operation() {
cout << "ConcreteComponent's normal operation!" << endl;
}
};
class Decorator : public Component {
public:
Decorator(Component *pcmp) : component(pcmp) {}
virtual ~Decorator() = default;
void operation() {
component->operation();
}
private:
Component *component;
};
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component *pcmp) : Decorator(pcmp) {}
virtual ~ConcreteDecoratorA() = default;
void addBehavior() {
cout << "addBehavior AAAA" << endl;
}
void operation() {
Decorator::operation();
addBehavior();
}
};
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component *pcmp) : Decorator(pcmp) {}
virtual ~ConcreteDecoratorB() = default;
void addBehavior() {
cout << "addBehavior BBBB" << endl;
}
void operation() {
Decorator::operation();
addBehavior();
}
};
int main() {
ConcreteComponent *concreteComponent = new ConcreteComponent();
concreteComponent->operation();
cout << "-----------" << endl;
Component *pA = new ConcreteDecoratorA(concreteComponent);
pA->operation();
cout << "-----------" << endl;
Component * pB = new ConcreteDecoratorB(pA);
pB->operation();
delete concreteComponent;
delete pA;
delete pB;
return 0;
}
ConcreteComponent's normal operation!
-----------
ConcreteComponent's normal operation!
addBehavior AAAA
-----------
ConcreteComponent's normal operation!
addBehavior AAAA
addBehavior BBBB
2. Go代码实现
package main
import "fmt"
type Pizza interface {
getPrice() int
}
type Base struct {
}
func (b *Base) getPrice() int {
return 15
}
type TomatoTopping struct {
pizza Pizza
}
func (t *TomatoTopping) getPrice() int {
pizzaPrice := t.pizza.getPrice()
return pizzaPrice + 10
}
type CheeseTopping struct {
pizza Pizza
}
func (c *CheeseTopping) getPrice() int {
pizzaPrice := c.pizza.getPrice()
return pizzaPrice + 20
}
func main() {
pizza := &Base{}
pizzaWithCheese := &CheeseTopping{
pizza: pizza,
}
pizzaWithCheeseAndTomato := &TomatoTopping{
pizza: pizzaWithCheese,
}
fmt.Printf("price is %d\n", pizzaWithCheeseAndTomato.getPrice())
}