【设计模式】【结构型模式(Structural Patterns)】之装饰模式(Decorator Pattern)
1. 设计模式原理说明
装饰模式(Decorator Pattern) 是一种结构型设计模式,它允许在不改变对象接口的前提下,动态地给对象增加额外的责任或功能。这种模式创建了一个装饰类,用于包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
主要角色
- Component(组件):定义了一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent(具体组件):定义了一个具体的对象,也可以给这个对象添加一些责任。
- Decorator(装饰器):持有一个
Component
对象的实例,并定义了一个与Component
接口一致的接口。 - ConcreteDecorator(具体装饰器):向组件添加新的责任,通常通过在其前后添加行为来实现。
2. UML 类图及解释
UML 类图
+-----------------+ +-----------------+
| Component | | ConcreteComponent|
|-----------------| |-----------------|
| + operation(): void| | + operation(): void|
+-----------------+ +-----------------+
^ ^
| |
| |
v v
+-----------------+
| Decorator |
|-----------------|
| - component: Component |
| + setComponent(component: Component)|
| + operation(): void |
+-----------------+
^
|
|
v
+-----------------+ +-----------------+
| ConcreteDecoratorA| | ConcreteDecoratorB|
|-----------------| |-----------------|
| + operation(): void| | + operation(): void|
| + addedBehavior(): void| | + addedBehavior(): void|
+-----------------+ +-----------------+
类图解释
- Component:定义了一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent:定义了一个具体的对象,也可以给这个对象添加一些责任。
- Decorator:持有一个
Component
对象的实例,并定义了一个与Component
接口一致的接口。装饰器可以在其前后添加行为。 - ConcreteDecoratorA 和 ConcreteDecoratorB:具体装饰器,向组件添加新的责任,通常通过在其前后添加行为来实现。
3. 代码案例及逻辑详解
Java 代码案例
// 组件接口
interface Component {
void operation();
}
// 具体组件
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
// 装饰器
abstract class Decorator implements Component {
protected Component component;
public void setComponent(Component component) {
this.component = component;
}
@Override
public void operation() {
if (component != null) {
component.operation();
}
}
}
// 具体装饰器 A
class ConcreteDecoratorA extends Decorator {
@Override
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() {
System.out.println("ConcreteDecoratorA added behavior");
}
}
// 具体装饰器 B
class ConcreteDecoratorB extends Decorator {
@Override
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() {
System.out.println("ConcreteDecoratorB added behavior");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent();
ConcreteDecoratorA decoratorA = new ConcreteDecoratorA();
ConcreteDecoratorB decoratorB = new ConcreteDecoratorB();
decoratorA.setComponent(component);
decoratorB.setComponent(decoratorA);
decoratorB.operation();
// 输出:
// ConcreteComponent operation
// ConcreteDecoratorA added behavior
// ConcreteDecoratorB added behavior
}
}
C++ 代码案例
#include <iostream>
// 组件接口
class Component {
public:
virtual void operation() = 0;
virtual ~Component() {}
};
// 具体组件
class ConcreteComponent : public Component {
public:
void operation() override {
std::cout << "ConcreteComponent operation" << std::endl;
}
};
// 装饰器
class Decorator : public Component {
protected:
Component* component;
public:
void setComponent(Component* component) {
this->component = component;
}
void operation() override {
if (component != nullptr) {
component->operation();
}
}
};
// 具体装饰器 A
class ConcreteDecoratorA : public Decorator {
public:
void operation() override {
Decorator::operation();
addedBehavior();
}
void addedBehavior() {
std::cout << "ConcreteDecoratorA added behavior" << std::endl;
}
};
// 具体装饰器 B
class ConcreteDecoratorB : public Decorator {
public:
void operation() override {
Decorator::operation();
addedBehavior();
}
void addedBehavior() {
std::cout << "ConcreteDecoratorB added behavior" << std::endl;
}
};
// 客户端
int main() {
Component* component = new ConcreteComponent();
Decorator* decoratorA = new ConcreteDecoratorA();
Decorator* decoratorB = new ConcreteDecoratorB();
decoratorA->setComponent(component);
decoratorB->setComponent(decoratorA);
decoratorB->operation();
// 输出:
// ConcreteComponent operation
// ConcreteDecoratorA added behavior
// ConcreteDecoratorB added behavior
delete component;
delete decoratorA;
delete decoratorB;
return 0;
}
Python 代码案例
from abc import ABC, abstractmethod
# 组件接口
class Component(ABC):
@abstractmethod
def operation(self):
pass
# 具体组件
class ConcreteComponent(Component):
def operation(self):
print("ConcreteComponent operation")
# 装饰器
class Decorator(Component):
def __init__(self, component: Component):
self._component = component
def operation(self):
if self._component:
self._component.operation()
# 具体装饰器 A
class ConcreteDecoratorA(Decorator):
def operation(self):
super().operation()
self.added_behavior()
def added_behavior(self):
print("ConcreteDecoratorA added behavior")
# 具体装饰器 B
class ConcreteDecoratorB(Decorator):
def operation(self):
super().operation()
self.added_behavior()
def added_behavior(self):
print("ConcreteDecoratorB added behavior")
# 客户端
if __name__ == "__main__":
component = ConcreteComponent()
decorator_a = ConcreteDecoratorA(component)
decorator_b = ConcreteDecoratorB(decorator_a)
decorator_b.operation()
# 输出:
# ConcreteComponent operation
# ConcreteDecoratorA added behavior
# ConcreteDecoratorB added behavior
Go 代码案例
package main
import "fmt"
// 组件接口
type Component interface {
Operation()
}
// 具体组件
type ConcreteComponent struct{}
func (c *ConcreteComponent) Operation() {
fmt.Println("ConcreteComponent operation")
}
// 装饰器
type Decorator struct {
component Component
}
func (d *Decorator) SetComponent(component Component) {
d.component = component
}
func (d *Decorator) Operation() {
if d.component != nil {
d.component.Operation()
}
}
// 具体装饰器 A
type ConcreteDecoratorA struct {
Decorator
}
func (c *ConcreteDecoratorA) Operation() {
c.Decorator.Operation()
c.AddedBehavior()
}
func (c *ConcreteDecoratorA) AddedBehavior() {
fmt.Println("ConcreteDecoratorA added behavior")
}
// 具体装饰器 B
type ConcreteDecoratorB struct {
Decorator
}
func (c *ConcreteDecoratorB) Operation() {
c.Decorator.Operation()
c.AddedBehavior()
}
func (c *ConcreteDecoratorB) AddedBehavior() {
fmt.Println("ConcreteDecoratorB added behavior")
}
// 客户端
func main() {
component := &ConcreteComponent{}
decoratorA := &ConcreteDecoratorA{Decorator: Decorator{component: component}}
decoratorB := &ConcreteDecoratorB{Decorator: Decorator{component: decoratorA}}
decoratorB.Operation()
// 输出:
// ConcreteComponent operation
// ConcreteDecoratorA added behavior
// ConcreteDecoratorB added behavior
}
4. 总结
装饰模式 是一种结构型设计模式,它允许在不改变对象接口的前提下,动态地给对象增加额外的责任或功能。这种模式通过创建装饰类来包装原有类,并在保持类方法签名完整性的前提下,提供了额外的功能。
主要优点
- 灵活性:可以在运行时动态地添加或删除对象的责任,而不需要修改现有的代码。
- 可扩展性:可以很容易地通过组合不同的装饰器来实现复杂的功能。
- 符合开闭原则:可以在不修改现有代码的情况下,通过添加新的装饰器来扩展功能。
主要缺点
- 增加了系统的复杂性:装饰模式会引入许多小类,这可能会使系统的设计变得更复杂。
- 调试困难:由于装饰器可以层层嵌套,调试时可能难以跟踪到最终的行为。
适用场景
- 当需要在运行时动态地给对象添加功能时。
- 当需要扩展类的功能,但又不想使用继承的方式时。
- 当系统需要提供多种可选功能,且这些功能可以自由组合时。