装饰器模式学习笔记

装饰器模式是一种结构型设计模式,用于在不改变底层对象结构的情况下,给对象增加功能。

设计原则

装饰器模式遵循以下设计原则:

  • 开放封闭原则:允许添加新功能而无需修改现有代码。
  • 单一职责原则:每个类应该只有一个引起它变化的原因。

实现方式

装饰器模式通过包裹一个已有的对象,把新的行为动态地添加到对象上。这种实现方式可以让我们在运行时动态地扩展一个对象的行为。

pythonCopy Code
class 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 对象的类,ConcreteDecoratorAConcreteDecoratorB 是继承自 Decorator 的具体装饰器类。

示例

假设我们正在开发一个扫雷游戏,现在有一个 Cell 类表示单元格,在游戏中需要为这个单元格添加一个标记,记录它是否被标记。这个时候,我们可以使用装饰器模式来添加这个功能。

pythonCopy Code
class 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() 方法获取包装后的字符串。

总结

装饰器模式可以让我们在运行时动态地给对象增加功能。它非常适用于需要对一个对象进行多次扩展的场景,而且可以避免编写大量相似的子类。但是,应该注意到装饰器模式会导致对象变得复杂,因为它们可以包含多个装饰器,而这些装饰器也可以包含其它装饰器。当对象变得太过复杂时,我们还是应该考虑重构代码,使其更加简洁易懂。