极简设计模式

Python 是一种高级编程语言,广泛应用于各种领域,如 Web 开发、数据分析、人工智能等。设计模式是一种在软件工程中常用的解决方案,用于解决特定问题。以下是 Python 设计模式的基本概念、架构和示例。

1. 简要

Python 设计模式是一种用于解决常见编程问题的模板。设计模式可以帮助程序员编写可维护、可扩展和可重用的代码。Python 设计模式可以分为以下几类:

  • 创建型模式:用于创建对象的最佳方式。
  • 结构型模式:用于组合对象和类以形成更大的结构。
  • 行为型模式:用于定义对象之间的交互和通信。

2. 架构

2.1 创建型模式:这类模式关注于对象的创建方式,旨在创建对象的最佳方式。包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。

  • 单例模式:确保一个类只有一个实例,并提供一个全局访问点。
  • 工厂方法模式:定义一个接口用于创建对象,但由子类决定要实例化的类是哪一个。
  • 抽象工厂模式:提供一个接口,用于创建一系列相关或依赖对象的家族,而不需要指定它们具体的类。
  • 建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 原型模式:通过复制现有的对象创建新对象,而不通过构造函数创建对象。

2.2 结构型模式:这类模式关注于类和对象之间的组合,旨在将对象组合成树形结构来表示“部分-整体”的层次结构。包括适配器模式、桥接模式、组合模式、装饰器模式、门面模式、享元模式和代理模式。

  • 适配器模式:允许不兼容接口的类一起工作,通过适配器类来转换接口。
  • 桥接模式:将抽象部分与实现部分分离,使它们可以独立地变化。
  • 组合模式:允许你将对象组合成树形结构来表示“部分-整体”的层次结构,使得客户以一致的方式处理单个对象和组合对象。
  • 装饰器模式:为对象添加一些额外的职责,而不改变其接口。
  • 门面模式:提供一个统一的接口,用来访问一组复杂系统的子系统。
  • 享元模式:用于实现对象的共享,以减少创建对象的数量并减少内存占用。
  • 代理模式:为其他对象提供一种代理以控制对这个对象的访问。

2.3 行为型模式:这类模式关注于对象之间的通信,旨在定义对象之间的交互和通信。包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

  • 职责链模式:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合。
  • 命令模式:将请求封装为一个对象,从而使用户和处理请求的对象解耦。
  • 解释器模式:为语言创建解释器,用来解释该语言中的句子。
  • 迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部的表示。
  • 中介者模式:定义了一个对象,该对象封装了一组对象之间的交互。
  • 备忘录模式:允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
  • 观察者模式:定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。
  • 状态模式:允许对象在内部状态改变时改变其行为,看起来好像修改了类一样。
  • 策略模式:定义了一系列算法,并将每一个算法封装起来,让它们可以互相替换。
  • 模板方法模式:定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。
  • 访问者模式:表示一个作用于某对象结构中的各元素的操作,它可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

3. 基本语法

Python 设计模式的基本语法包括类、对象、继承、多态、封装等概念。以下是一个简单的 Python 类示例:

class Animal:
    def __init__(self, name):
        self.name = name
    def speak(self):
        raise NotImplementedError("Subclass must implement speak method")
class Dog(Animal):
    def speak(self):
        return "Woof!"
class Cat(Animal):
    def speak(self):
        return "Meow!"
# 创建对象
dog = Dog("Buddy")
cat = Cat("Whiskers")
# 调用方法
print(dog.speak())  # 输出:Woof!
print(cat.speak())  # 输出:Meow!

在这个示例中,我们定义了一个名为 Animal 的基类,包含一个 speak 方法。然后我们创建了两个子类 DogCat,分别实现了 speak 方法。最后,我们创建了两个对象 dogcat,并调用了它们的 speak 方法。

4. 内容

以下是一些常见 Python 设计模式的示例:

4.1 单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点。

class Singleton:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2)  # 输出:True

4.2 工厂方法模式

工厂方法模式定义一个接口用于创建对象,但由子类决定要实例化的类是哪一个。

from abc import ABC, abstractmethod
class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass
class Dog(Animal):
    def speak(self):
        return "Woof!"
class Cat(Animal):
    def speak(self):
        return "Meow!"
class AnimalFactory(ABC):
    @abstractmethod
    def create_animal(self):
        pass
class DogFactory(AnimalFactory):
    def create_animal(self):
        return Dog()
class CatFactory(AnimalFactory):
    def create_animal(self):
        return Cat()
# 创建工厂对象
dog_factory = DogFactory()
cat_factory = CatFactory()
# 创建动物对象
dog = dog_factory.create_animal()
cat = cat_factory.create_animal()
# 调用方法
print(dog.speak())  # 输出:Woof!
print(cat.speak())  # 输出:Meow!

当然,让我们继续探讨抽象工厂模式。

4.3 抽象工厂模式

抽象工厂模式提供了一个接口,用于创建一系列相关或依赖对象的家族,而不需要指定它们具体的类。

class AbstractFactory:
    @abstractmethod
    def create_productA(self):
        pass
    @abstractmethod
    def create_productB(self):
        pass
class ConcreteFactory1:
    def create_productA(self):
        return ProductA("ProductA1")
    def create_productB(self):
        return ProductB("ProductB1")
class ConcreteFactory2:
    def create_productA(self):
        return ProductA("ProductA2")
    def create_productB(self):
        return ProductB("ProductB2")
class ProductA:
    def __init__(self, name):
        self.name = name
class ProductB:
    def __init__(self, name):
        self.name = name
# 使用抽象工厂模式
factory1 = ConcreteFactory1()
productA1 = factory1.create_productA()
productB1 = factory1.create_productB()
factory2 = ConcreteFactory2()
productA2 = factory2.create_productA()
productB2 = factory2.create_productB()
print(productA1.name)  # 输出:ProductA1
print(productB1.name)  # 输出:ProductB1
print(productA2.name)  # 输出:ProductA2
print(productB2.name)  # 输出:ProductB2

在这个示例中,AbstractFactory 是一个抽象工厂类,它定义了创建产品A和产品B的方法。ConcreteFactory1ConcreteFactory2 是具体的工厂类,它们实现了抽象工厂的方法。ProductAProductB 是产品类,它们分别包含自己的名字属性。
通过抽象工厂模式,我们可以在不指定具体的产品类的情况下,创建和返回产品对象。这样,我们可以更容易地扩展或更改产品类,而不影响使用这些产品的应用程序。

4.4 建造者模式

建造者模式用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

class Builder(ABC):
    @abstractmethod
    def build(self):
        pass
class ConcreteBuilderA(Builder):
    def build(self):
        self.product.part1 = "Part 1"
        self.product.part2 = "Part 2"
        self.product.part3 = "Part 3"
        return self.product
class Director:
    def __init__(self):
        self._builder = None
    def set_builder(self, builder):
        self._builder = builder
    def construct(self):
        if not self._builder:
            self._builder = ConcreteBuilderA()
        self._builder.build()
    def get_product(self):
        return self._builder.product
class Product:
    def __init__(self):
        self.part1 = None
        self.part2 = None
        self.part3 = None
# 使用建造者模式
director = Director()
director.set_builder(ConcreteBuilderA())
director.construct()
product = director.get_product()
print(product.part1)  # 输出:Part 1
print(product.part2)  # 输出:Part 2
print(product.part3)  # 输出:Part 3

在这个示例中,Builder 是一个抽象建造者类,它定义了一个构建方法。ConcreteBuilderA 是一个具体的建造者类,它实现了构建方法。Director 是一个导演类,它负责指导建造过程。Product 是一个产品类,它包含构建好的部分。

4.5 原型模式

原型模式通过复制现有的对象创建新对象,而不通过构造函数创建对象。

class Animal:
    def __init__(self, name):
        self.name = name
    def speak(self):
        raise NotImplementedError("Subclass must implement speak method")
class Dog(Animal):
    def speak(self):
        return "Woof!"
class Cat(Animal):
    def speak(self):
        return "Meow!"
class Prototype:
    def __init__(self):
        self.animals = []
    def add_animal(self, animal):
        self.animals.append(animal)
    def clone_animal(self, animal):
        return animal.copy()
# 使用原型模式
prototype = Prototype()
prototype.add_animal(Dog("Buddy"))
prototype.add_animal(Cat("Whiskers"))
cloned_dog = prototype.clone_animal(prototype.animals[0])
cloned_cat = prototype.clone_animal(prototype.animals[1])
print(cloned_dog.speak())  # 输出:Woof!
print(cloned_cat.speak())  # 输出:Meow!

在这个示例中,Animal 是一个基类,它包含了一个名字属性。DogCatAnimal 的子类,它们实现了 speak 方法。Prototype 类管理一组动物,并可以克隆它们。

4.6 适配器模式

适配器模式允许不兼容接口的类一起工作,通过适配器类来转换接口。

class Target:
    def request(self):
        return "Target: The default target's behavior."
class Adaptee:
    def specific_request(self):
        return ".eetpadA eht fo roivaheb laicepS"
class Adapter(Target):
    def __init__(self, adaptee):
        self._adaptee = adaptee
    def request(self):
        return f"Adapter: (TRANSLATED) {self._adaptee.specific_request()[::-1]}"
# 使用适配器
adaptee = Adaptee()
adapter = Adapter(adaptee)
print(adapter.request())  # 输出:Adapter: (TRANSLATED) Special behavior of the Adaptee.

在这个示例中,Adaptee 类有一个 specific_request 方法,但其接口与 Target 类的 request 方法不兼容。Adapter 类通过继承 Target 类并包装一个 Adaptee 实例,实现了适配器模式,使得 Adaptee 能够与 Target 兼容。

4.7 桥接模式

桥接模式将抽象部分与实现部分分离,使它们可以独立地变化。

class Implementation(ABC):
    def operation_implementation(self):
        pass
class ConcreteImplementationA(Implementation):
    def operation_implementation(self):
        return "ConcreteImplementationA: Here's the result on the platform A."
class ConcreteImplementationB(Implementation):
    def operation_implementation(self):
        return "ConcreteImplementationB: Here's the result on the platform B."
class Abstraction:
    def __init__(self, implementation):
        self._implementation = implementation
    def operation(self):
        return f"Abstraction: Base operation with:\n{self._implementation.operation_implementation()}"
class ExtendedAbstraction(Abstraction):
    def operation(self):
        return f"ExtendedAbstraction: Extended operation with:\n{self._implementation.operation_implementation()}"
# 使用桥接模式
implementation = ConcreteImplementationA()
abstraction = Abstraction(implementation)
print(abstraction.operation())
implementation = ConcreteImplementationB()
abstraction = ExtendedAbstraction(implementation)
print(abstraction.operation())

在这个示例中,Implementation 是一个实现部分的抽象类,ConcreteImplementationAConcreteImplementationB 是具体的实现。Abstraction 是一个抽象部分的类,它依赖于实现部分。ExtendedAbstraction 是一个扩展了抽象部分的类。通过桥接模式,抽象部分和实现部分可以独立地变化,从而提高了系统的灵活性。

4.8 组合模式

组合模式允许你将对象组合成树形结构来表示“部分-整体”的层次结构,使得客户以一致的方式处理单个对象和组合对象。

class Component(ABC):
    def __init__(self, name):
        self._name = name
    @abstractmethod
    def operation(self):
        pass
class Leaf(Component):
    def operation(self):
        return f"{self._name} is a leaf node."
class Composite(Component):
    def __init__(self, name):
        super().__init__(name)
        self._children = []
    def add(self, component):
        self._children.append(component)
    def remove(self, component):
        self._children.remove(component)
    def operation(self):
        results = []
        for child in self._children:
            results.append(child.operation())
        return f"{self._name} composite result: {' | '.join(results)}"
# 使用组合模式
root = Composite("Root")
root.add(Leaf("Leaf A"))
root.add(Leaf("Leaf B"))
composite = Composite("Composite X")
composite.add(Leaf("Leaf XA"))
composite.add(Leaf("Leaf XB"))
root.add(composite)
print(root.operation())
# 输出:Root composite result: Leaf A is a leaf node. | Leaf B is a leaf node. | Composite X composite result: Leaf XA is a leaf node. | Leaf XB is a leaf node.

在这个示例中,Component 是一个抽象类,它定义了所有对象的接口。Leaf 是一个叶子节点,它实现了组件接口。Composite 是一个复合节点,它可以包含其他组件(叶节点或复合节点)。这样,我们就可以以统一的方式处理单个对象和组合对象。

4.9 装饰器模式

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。

from functools import wraps
def make_bold(func):
    @wraps(func)
    def wrapper():
        return f"{func()}"
    return wrapper
def make_italic(func):
    @wraps(func)
    def wrapper():
        return f"{func()}"
    return wrapper
@make_bold
@make_italic
def say_hello():
    return "Hello!"
print(say_hello())  # 输出:Hello!

在这个示例中,我们定义了两个装饰器 make_boldmake_italic,它们分别将文本加粗和斜体。然后我们使用这两个装饰器来装饰 say_hello 函数,使其返回的文本同时具有加粗和斜体效果。

4.10 门面模式

门面模式提供一个统一的接口,用来访问一组复杂系统的子系统。

class Facade:
    def __init__(self):
        self.subsystem1 = None
        self.subsystem2 = None
    def attach(self, subsystem):
        if subsystem.name == "subsystem1":
            self.subsystem1 = subsystem
        elif subsystem.name == "subsystem2":
            self.subsystem2 = subsystem
    def operation(self):
        if self.subsystem1:
            self.subsystem1.operate()
        if self.subsystem2:
            self.subsystem2.operate()
# 使用门面模式
facade = Facade()
facade.attach(Subsystem1())
facade.attach(Subsystem2())
facade.operation()  # 输出:Subsystem1: Operation 1
                      # Subsystem2: Operation 2

在这个示例中,Facade 是一个门面类,它封装了 Subsystem1Subsystem2。客户端只需要与 Facade 交互,而不需要直接与子系统交互。
Subsystem1Subsystem2 是具体的子系统类,它们实现了操作方法。通过门面模式,我们提供了一个统一的接口来访问子系统,使得客户端代码更加简洁和易于维护。

4.11 享元模式

享元模式用于实现对象的共享,以减少创建对象的数量并减少内存占用。

class Flyweight:
    def __init__(self, shared_state):
        self._shared_state = shared_state
    def operation(self, unique_state):
        return f"Flyweight: Displaying shared state ({self._shared_state}) and unique state ({unique_state})"
class FlyweightFactory:
    def __init__(self):
        self._flyweights = {}
    def get_flyweight(self, key):
        if key not in self._flyweights:
            self._flyweights[key] = Flyweight(key)
        return self._flyweights[key]
# 使用享元模式
factory = FlyweightFactory()
flyweight1 = factory.get_flyweight("Shared State 1")
flyweight2 = factory.get_flyweight("Shared State 2")
flyweight3 = factory.get_flyweight("Shared State 1")
print(flyweight1.operation("Unique State 1"))
print(flyweight2.operation("Unique State 2"))
print(flyweight3.operation("Unique State 3"))

在这个示例中,Flyweight 类是一个享元类,它包含共享状态。FlyweightFactory 类负责创建和管理享元对象。通过享元模式,我们可以共享多个对象中的相同部分,从而减少对象创建的数量。

4.12 代理模式

代理模式为其他对象提供一种代理以控制对这个对象的访问。

class Subject(ABC):
    @abstractmethod
    def request(self):
        pass
class RealSubject(Subject):
    def request(self):
        return "RealSubject: Handling request."
class Proxy(Subject):
    def __init__(self, real_subject):
        self._real_subject = real_subject
    def request(self):
        if self.check_access():
            return self._real_subject.request()
        else:
            return "Proxy: Access denied."
    def check_access(self):
        # 这里可以添加更复杂的逻辑来检查访问权限
        return True
# 使用代理模式
real_subject = RealSubject()
proxy = Proxy(real_subject)
print(proxy.request())  # 输出:RealSubject: Handling request.

在这个示例中,Proxy 类代理了 RealSubject 类的行为。Proxy 类的 request 方法首先检查是否有访问权限,如果有,则调用 RealSubjectrequest 方法;如果没有,则拒绝访问。

4.13 职责链模式

职责链模式使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合。

class Handler(ABC):
    def __init__(self, successor=None):
        self._successor = successor
    def handle(self, request):
        res = self.check_range(request)
        if not res and self._successor is not None:
            self._successor.handle(request)
    @abstractmethod
    def check_range(self, request):
        pass
class ConcreteHandler1(Handler):
    def check_range(self, request):
        if 0 <= request < 10:
            print(f"ConcreteHandler1: Handle request {request}")
            return True
        return False
class ConcreteHandler2(Handler):
    def check_range(self, request):
        if 10 <= request < 20:
            print(f"ConcreteHandler2: Handle request {request}")
            return True
        return False
class DefaultHandler(Handler):
    def check_range(self, request):
        print(f"DefaultHandler: Handle request {request}")
        return True
# 使用职责链模式
handler1 = ConcreteHandler1()
handler2 = ConcreteHandler2()
default_handler = DefaultHandler()
handler1._successor = handler2
handler2._successor = default_handler
handler1.handle(5)  # 输出:ConcreteHandler1: Handle request 5
handler1.handle(15)  # 输出:ConcreteHandler2: Handle request 15
handler1.handle(25)  # 输出:DefaultHandler: Handle request 25

在这个示例中,Handler 是一个处理请求的抽象类,ConcreteHandler1ConcreteHandler2DefaultHandler 是具体的处理类。每个处理类都有一个指向下一个处理类的引用,如果一个处理类不能处理请求,它会将请求传递给下一个处理类。

4.14 命令模式

命令模式将请求封装为一个对象,从而使用户和处理请求的对象解耦。

from abc import ABC, abstractmethod
class Command(ABC):
    @abstractmethod
    def execute(self):
        pass
class ConcreteCommand(Command):
    def __init__(self, receiver):
        self._receiver = receiver
    def execute(self):
        self._receiver.action()
class Receiver:
    def action(self):
        print("Receiver: Action executed.")
class Invoker:
    def __init__(self, command):
        self._command = command
    def set_command(self, command):
        self._command = command
    def execute_command(self):
        self._com
        mand.execute()
# 使用命令模式
receiver = Receiver()
command = ConcreteCommand(receiver)
invoker = Invoker(command)
invoker.execute_command()  # 输出:Receiver: Action executed.

在这个示例中,Command 接口定义了执行操作的方法。ConcreteCommand 类实现了 Command 接口,并持有一个接收者的引用。Receiver 类是执行实际操作的对象。Invoker 类负责调用命令对象执行操作。这样,请求的发起者和请求的执行者之间就解耦了。

4.15 解释器模式

解释器模式为语言创建解释器,用来解释该语言中的句子。

class Expression(ABC):
    def interpret(self, context):
        pass
class TerminalExpression(Expression):
    def __init__(self, data):
        self.data = data
    def interpret(self, context):
        if self.data in context:
            return True
        return False
class OrExpression(Expression):
    def __init__(self, expression1, expression2):
        self.expression1 = expression1
        self.expression2 = expression2
    def interpret(self, context):
        return self.expression1.interpret(context) or self.expression2.interpret(context)
class AndExpression(Expression):
    def __init__(self, expression1, expression2):
        self.expression1 = expression1
        self.expression2 = expression2
    def interpret(self, context):
        return self.expression1.interpret(context) and self.expression2.interpret(context)
# 使用解释器模式
context = {"A": True, "B": True, "C": False}
expression = AndExpression(
    TerminalExpression("A"),
    OrExpression(TerminalExpression("B"), TerminalExpression("C"))
)
print(expression.interpret(context))  # 输出:True

在这个示例中,Expression 是一个抽象表达式类,TerminalExpressionOrExpressionAndExpression 是具体的表达式类。通过组合这些表达式,我们可以创建复杂的规则并解释它们。

4.16 迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部的表示。

class Iterator(ABC):
    def __init__(self, collection):
        self._collection = collection
        self._current = 0
    def first(self):
        return self._collection[0]
    def next(self):
        ret = None
        if self._current < len(self._collection):
            ret = self._collection[self._current]
            self._current += 1
        return ret
    def has_next(self):
        return self._current < len(self._collection)
class Aggregate(ABC):
    def create_iterator(self):
        return Iterator(self)
class ConcreteAggregate(Aggregate):
    def __init__(self, items):
        self._items = items
    def create_iterator(self):
        return Iterator(self._items)
# 使用迭代器模式
items = [1, 2, 3, 4, 5]
aggregate = ConcreteAggregate(items)
iterator = aggregate.create_iterator()
while iterator.has_next():
    print(iterator.next())  # 输出:1 2 3 4 5

在这个示例中,Iterator 类是一个迭代器,它提供了访问聚合对象元素的方法。Aggregate 类是一个抽象聚合类,它定义了创建迭代器的方法。ConcreteAggregate 类是一个具体的聚合类,它实现了创建迭代器的方法。通过这种方式,可以顺序访问聚合对象中的元素,而不需要知道其内部的表示。

4.17 中介者模式

中介者模式定义了一个对象,该对象封装了一组对象之间的交互。它降低了对象之间的耦合,使得对象之间的交互更加清晰。

class Colleague(ABC):
    def __init__(self, mediator):
        self._mediator = mediator
    def send(self, message):
        self._mediator.send(message, self)
class ConcreteColleague1(Colleague):
    def notify(self, message):
        print(f"ConcreteColleague1: Received message '{message}'")
class ConcreteColleague2(Colleague):
    def notify(self, message):
        print(f"ConcreteColleague2: Received message '{message}'")
class Mediator(ABC):
    def __init__(self):
        self._colleagues = []
    def add_colleague(self, colleague):
        self._colleagues.append(colleague)
    @abstractmethod
    def send(self, message, colleague):
        pass
class ConcreteMediator(Mediator):
    def send(self, message, colleague):
        for c in self._colleagues:
            if c != colleague:
                c.notify(message)
# 使用中介者模式
mediator = ConcreteMediator()
colleague1 = ConcreteColleague1(mediator)
colleague2 = ConcreteColleague2(mediator)
mediator.add_colleague(colleague1)
mediator.add_colleague(colleague2)
colleague1.send("Hello from Colleague1")
colleague2.send("Hello from Colleague2")

在这个示例中,Colleague 是一个抽象同事类,它知道中介者并可以向中介者发送消息。ConcreteColleague1ConcreteColleague2 是具体的同事类,它们实现了通知方法。Mediator 是一个抽象中介者类,它定义了同事对象注册和发送消息的方法。ConcreteMediator 是一个具体的中介者类,它协调同事对象之间的通信。

4.18 备忘录模式

备忘录模式允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

class Originator:
    def __init__(self, state):
        self._state = state
    def set_state(self, state):
        self._state = state
    def save_to_memento(self):
        return Memento(self._state)
    def restore_from_memento(self, memento):
        self._state = memento.get_state()
class Memento:
    def __init__(self, state):
        self._state = state
    def get_state(self):
        return self._state
class Caretaker:
    def __init__(self, originator):
        self._mementos = []
        self._originator = originator
    def backup(self):
        self._mementos.append(self._originator.save_to_memento())
    def undo(self):
        if not self._mementos:
            return
        memento = self._mementos.pop()
        self._originator.restore_from_memento(memento)
# 使用备忘录模式
originator = Originator("State1")
caretaker = Caretaker(originator)
caretaker.backup()
originator.set_state("State2")
caretaker.backup()
originator.set_state("State3")
caretaker.undo()  # 恢复到 State2
print(originator._state)  # 输出:State2
caretaker.undo()  # 恢复到 State1
print(originator._state)  # 输出:State1

在这个示例中,Originator 类是负责创建备忘录的对象,Memento 类是备忘录,它存储了 Originator 的状态。Caretaker 类负责管理备忘录。通过这种方式,可以保存和恢复对象的状态,而不需要知道对象内部的实现细节。

4.19 观察者模式

观察者模式定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。

from abc import ABC, abstractmethod
class Observer(ABC):
    @abstractmethod
    def update(self, subject):
        pass
class Subject(ABC):
    @abstractmethod
    def attach(self, observer):
        pass
    @abstractmethod
    def detach(self, observer):
        pass
    @abstractmethod
    def notify(self):
        pass
class ConcreteSubject(Subject):
    _observers = []
    _subject_state = None
    def attach(self, observer):
        if observer not in self._observers:
            self._observers.append(observer)
    def detach(self, observer):
        try:
            self._observers.remove(observer)
        except ValueError:
            pass
    def notify(self):
        for observer in self._observers:
            observer.update(self)
    def set_state(self, state):
        self._subject_state = state
        self.notify()
    def get_state(self):
        return self._subject_state
class ConcreteObserver(Observer):
    def update(self, subject):
        if subject.get_state() < 0:
            print("ConcreteObserver: Reacted to the event.")
# 创建对象
subject = ConcreteSubject()
observer = ConcreteObserver()
# 注册观察者
subject.attach(observer)
# 改变主题状态
subject.set_state(-1)  # 输出:ConcreteObserver: Reacted to the event.

在这个示例中,我们定义了两个抽象类 ObserverSubject,以及它们的具体实现 ConcreteObserverConcreteSubject。当 ConcreteSubject 的状态改变时,它会通知所有注册的观察者。

4.20 状态模式

状态模式允许对象在内部状态改变时改变其行为,看起来好像修改了类一样。

from abc import ABC, abstractmethod
class State(ABC):
    @abstractmethod
    def handle(self, context):
        pass
class ConcreteStateA(State):
    def handle(self, context):
        print("ConcreteStateA handle")
        context.state = ConcreteStateB()
class ConcreteStateB(State):
    def handle(self, context):
        print("ConcreteStateB handle")
        context.state = ConcreteStateA()
class Context:
    def __init__(self, state):
        self.state = state
    def request(self):
        self.state.handle(self)
# 使用状态模式
context = Context(ConcreteStateA())
context.request()  # 输出:ConcreteStateA handle
context.request()  # 输出:ConcreteStateB handle
context.request()  # 输出:ConcreteStateA handle

在这个示例中,Context 类依赖于一个抽象状态类 State,它有两个具体状态 ConcreteStateAConcreteStateBContext 类的 request 方法委托给当前状态来处理,而状态的改变会导致 Context 的行为发生变化。

4.21 策略模式

策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。

from abc import ABC, abstractmethod
class Strategy(ABC):
    @abstractmethod
    def do_algorithm(self, data):
        pass
class ConcreteStrategyA(Strategy):
    def do_algorithm(self, data):
        return data * 2
class ConcreteStrategyB(Strategy):
    def do_algorithm(self, data):
        return data ** 2
class Context:
    def __init__(self, strategy):
        self._strategy = strategy
    def set_strategy(self, strategy):
        self._strategy = strategy
    def execute_strategy(self, data):
        return self._strategy.do_algorithm(data)
# 使用策略
context = Context(ConcreteStrategyA())
print(context.execute_strategy(5))  # 输出:10
context.set_strategy(ConcreteStrategyB())
print(context.execute_strategy(5))  # 输出:25

在这个示例中,我们定义了一个 Strategy 抽象类和两个具体的策略 ConcreteStrategyAConcreteStrategyBContext 类使用其中一个策略来执行算法。通过改变策略,我们可以轻松地更改算法的行为。

4.22 模板方法模式

模板方法模式定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。这样,可以在不改变算法结构的情况下重新定义算法的某些特定步骤。

from abc import ABC, abstractmethod
class AbstractClass(ABC):
    def template_method(self):
        self.step1()
        self.step2()
    def step1(self):
        print("AbstractClass: Step 1")
    @abstractmethod
    def step2(self):
        pass
class ConcreteClass(AbstractClass):
    def step2(self):
        print("ConcreteClass: Step 2")
# 使用模板方法
concrete_class = ConcreteClass()
concrete_class.template_method()

在这个示例中,AbstractClass 定义了一个模板方法 template_method,它调用了一个或多个抽象操作 step1step2ConcreteClass 实现了这些抽象操作。这样,template_method 的算法结构保持不变,但具体的步骤实现可以在子类中改变。

4.23 访问者模式

访问者模式表示一个作用于某对象结构中的各元素的操作,它可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

class Visitor(ABC):
    @abstractmethod
    def visit_concrete_element_a(self, element):
        pass
    @abstractmethod
    def visit_concrete_element_b(self, element):
        pass
class ConcreteVisitor1(Visitor):
    def visit_concrete_element_a(self, element):
        print(f"ConcreteVisitor1: Visiting ConcreteElementA")
    def visit_concrete_element_b(self, element):
        print(f"ConcreteVisitor1: Visiting ConcreteElementB")
class ConcreteVisitor2(Visitor):
    def visit_concrete_element_a(self, element):
        print(f"ConcreteVisitor2: Visiting ConcreteElementA")
    def visit_concrete_element_b(self, element):
        print(f"ConcreteVisitor2: Visiting ConcreteElementB")
class Element(ABC):
    def accept(self, visitor):
        pass
class ConcreteElementA(Element):
    def accept(self, visitor):
        visitor.visit_concrete_element_a(self)
class ConcreteElementB(Element):
    def accept(self, visitor):
        visitor.visit_concrete_element_b(self)
# 使用访问者模式
element_a = ConcreteElementA()
element_b = ConcreteElementB()
visitor1 = ConcreteVisitor1()
visitor2 = ConcreteVisitor2()
element_a.accept(visitor1)
element_b.accept(visitor1)
element_a.accept(visitor2)
element_b.accept(visitor2)

在这个示例中,Visitor 是一个抽象访问者类,它定义了访问各种元素的方法。ConcreteVisitor1ConcreteVisitor2 是具体的访问者类,它们实现了访问方法。Element 是一个抽象元素类,它定义了接受访问者的方法。ConcreteElementAConcreteElementB 是具体的元素类,它们接受访问者并调用访问者的相应方法。

你可能感兴趣的:(python)