装饰器模式学习笔记
装饰器模式是一种结构型设计模式,用于在不改变底层对象结构的情况下,给对象增加功能。
设计原则
装饰器模式遵循以下设计原则:
- 开放封闭原则:允许添加新功能而无需修改现有代码。
- 单一职责原则:每个类应该只有一个引起它变化的原因。
实现方式
装饰器模式通过包裹一个已有的对象,把新的行为动态地添加到对象上。这种实现方式可以让我们在运行时动态地扩展一个对象的行为。
pythonCopy Codeclass Component:
def operation(self) -> str:
pass
class ConcreteComponent(Component):
def operation(self) -> str:
return "ConcreteComponent"
class Decorator(Component):
_component: Component = None
def __init__(self, component: Component) -> None:
self._component = component
@property
def component(self) -> str:
return self._component
def operation(self) -> str:
return self._component.operation()
class ConcreteDecoratorA(Decorator):
def operation(self) -> str:
return f"ConcreteDecoratorA({self.component.operation()})"
class ConcreteDecoratorB(Decorator):
def operation(self) -> str:
return f"ConcreteDecoratorB({self.component.operation()})"
在这个例子中,Component
类定义了一个接口 operation()
,ConcreteComponent
是一个实现了 Component
接口的类,Decorator
是一个同时实现了 Component
接口并包含一个 Component
对象的类,ConcreteDecoratorA
和 ConcreteDecoratorB
是继承自 Decorator
的具体装饰器类。
示例
假设我们正在开发一个扫雷游戏,现在有一个 Cell
类表示单元格,在游戏中需要为这个单元格添加一个标记,记录它是否被标记。这个时候,我们可以使用装饰器模式来添加这个功能。
pythonCopy Codeclass Cell:
def __init__(self, x, y):
self.x = x
self.y = y
self.is_bomb = False
def __str__(self):
return f"({self.x}, {self.y}), is_bomb: {self.is_bomb}"
class LabelDecorator(Decorator):
def __init__(self, component: Component, label: str) -> None:
super().__init__(component)
self.label = label
def operation(self) -> str:
return f"{self.label}: {self.component.operation()}"
cell = Cell(x=1, y=2)
print(cell)
cell = LabelDecorator(component=cell, label="Flagged")
print(cell)
在这个例子中,Cell
表示一个单元格,包含了单元格的坐标和是否是地雷等信息。我们想要给这个单元格添加一个标记来记录它是否被标记,于是我们定义了一个 LabelDecorator
类作为装饰器,可以为一个单元格对象添加标记。通过调用 LabelDecorator
构造函数并传入一个单元格对象和一个标记名,我们就可以为它添加上标记,然后通过 operation()
方法获取包装后的字符串。
总结
装饰器模式可以让我们在运行时动态地给对象增加功能。它非常适用于需要对一个对象进行多次扩展的场景,而且可以避免编写大量相似的子类。但是,应该注意到装饰器模式会导致对象变得复杂,因为它们可以包含多个装饰器,而这些装饰器也可以包含其它装饰器。当对象变得太过复杂时,我们还是应该考虑重构代码,使其更加简洁易懂。