常见的设计模式

引言

设计模式是一套被反复验证的解决方案,它帮助我们处理软件开发过程中常见的问题。通过设计模式,我们可以构建更具扩展性、可维护性和灵活性的系统。接下来,我们将介绍常见的设计模式,并为每种模式提供详细的代码示例。

常见的设计模式

1. 策略模式(Strategy Pattern)

定义

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法的变化独立于使用算法的客户。

代码示例

from abc import ABC, abstractmethod
from typing import Protocol

# 策略接口
class Strategy(ABC):
    @abstractmethod
    def execute(self, a: int, b: int) -> int:
        pass

# 具体策略:加法
class AddStrategy(Strategy):
    def execute(self, a: int, b: int) -> int:
        return a + b

# 具体策略:减法
class SubtractStrategy(Strategy):
    def execute(self, a: int, b: int) -> int:
        return a - b

# 上下文:根据传入的策略执行相应的算法
class Context:
    def __init__(self, strategy: Strategy) -> None:
        self.strategy = strategy

    def execute_strategy(self, a: int, b: int) -> int:
        return self.strategy.execute(a, b)

# 使用策略
add_strategy = AddStrategy()
context = Context(add_strategy)
print(context.execute_strategy(5, 3))  # 输出:8

subtract_strategy = SubtractStrategy()
context.strategy = subtract_strategy
print(context.execute_strategy(5, 3))  # 输出:2

2. 工厂模式(Factory Pattern)

定义

工厂模式提供了一种创建对象的方式,允许将对象的创建逻辑封装在工厂类中,而不是直接在代码中实例化对象。

代码示例

from typing import Type

# 产品接口
class Product(ABC):
    @abstractmethod
    def operation(self) -> str:
        pass

# 具体产品A
class ConcreteProductA(Product):
    def operation(self) -> str:
        return "Product A"

# 具体产品B
class ConcreteProductB(Product):
    def operation(self) -> str:
        return "Product B"

# 工厂类
class Creator:
    def factory_method(self, product_type: str) -> Product:
        if product_type == "A":
            return ConcreteProductA()
        elif product_type == "B":
            return ConcreteProductB()
        else:
            raise ValueError("Unknown product type")

# 使用工厂创建对象
creator = Creator()
product_a = creator.factory_method("A")
print(product_a.operation())  # 输出:Product A

product_b = creator.factory_method("B")
print(product_b.operation())  # 输出:Product B

3. 单例模式(Singleton Pattern)

定义

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

代码示例

class Singleton:
    _instance: "Singleton" = None
    
    def __new__(cls) -> "Singleton":
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

# 测试单例模式
singleton1 = Singleton()
singleton2 = Singleton()

print(singleton1 is singleton2)  # 输出:True,确保两个实例是同一个

4. 观察者模式(Observer Pattern)

定义

观察者模式定义了对象之间一对多的依赖关系,一个对象状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。

代码示例

from abc import ABC, abstractmethod
from typing import List

# 主题接口
class Subject(ABC):
    @abstractmethod
    def add_observer(self, observer: "Observer") -> None:
        pass

    @abstractmethod
    def remove_observer(self, observer: "Observer") -> None:
        pass

    @abstractmethod
    def notify(self, message: str) -> None:
        pass

# 观察者接口
class Observer(ABC):
    @abstractmethod
    def update(self, message: str) -> None:
        pass

# 具体主题
class ConcreteSubject(Subject):
    def __init__(self) -> None:
        self._observers: List[Observer] = []

    def add_observer(self, observer: Observer) -> None:
        self._observers.append(observer)

    def remove_observer(self, observer: Observer) -> None:
        self._observers.remove(observer)

    def notify(self, message: str) -> None:
        for observer in self._observers:
            observer.update(message)

# 具体观察者
class ConcreteObserver(Observer):
    def __init__(self, name: str) -> None:
        self.name = name

    def update(self, message: str) -> None:
        print(f"{self.name} received message: {message}")

# 使用观察者模式
subject = ConcreteSubject()
observer1 = ConcreteObserver("Observer 1")
observer2 = ConcreteObserver("Observer 2")

subject.add_observer(observer1)
subject.add_observer(observer2)

subject.notify("State changed!")  # 输出:Observer 1 received message: State changed! 和 Observer 2 received message: State changed!

5. 适配器模式(Adapter Pattern)

定义

适配器模式将一个类的接口转换成客户端希望的另一个接口,使得原本接口不兼容的类可以一起工作。

代码示例

from abc import ABC, abstractmethod

# 目标接口
class Target(ABC):
    @abstractmethod
    def request(self) -> str:
        pass

# 被适配者接口
class Adaptee:
    def specific_request(self) -> str:
        return "Specific request"

# 适配器类
class Adapter(Target):
    def __init__(self, adaptee: Adaptee) -> None:
        self.adaptee = adaptee

    def request(self) -> str:
        return self.adaptee.specific_request()

# 使用适配器模式
adaptee = Adaptee()
adapter = Adapter(adaptee)
print(adapter.request())  # 输出:Specific request

6. 装饰器模式(Decorator Pattern)

定义

装饰器模式允许动态地向对象添加额外的职责和行为,而不修改对象的结构。

代码示例

from typing import Protocol

# 组件接口
class Coffee(Protocol):
    def cost(self) -> int:
        pass

# 具体组件:普通咖啡
class BasicCoffee(Coffee):
    def cost(self) -> int:
        return 5

# 装饰器类
class CoffeeDecorator(Coffee):
    def __init__(self, coffee: Coffee) -> None:
        self._coffee = coffee

    def cost(self) -> int:
        return self._coffee.cost()

# 具体装饰器:加奶
class MilkDecorator(CoffeeDecorator):
    def cost(self) -> int:
        return self._coffee.cost() + 2

# 具体装饰器:加糖
class SugarDecorator(CoffeeDecorator):
    def cost(self) -> int:
        return self._coffee.cost() + 1

# 使用装饰器模式
coffee = BasicCoffee()
print(coffee.cost())  # 输出:5

milk_coffee = MilkDecorator(coffee)
print(milk_coffee.cost())  # 输出:7

milk_sugar_coffee = SugarDecorator(milk_coffee)
print(milk_sugar_coffee.cost())  # 输出:8

总结

通过上述示例,我们了解了 策略模式工厂模式单例模式观察者模式适配器模式装饰器模式。每种设计模式都有其特定的应用场景,帮助开发者在设计软件系统时,使得系统更具灵活性、可扩展性和可维护性。掌握这些设计模式不仅能提升代码的质量,还能增强代码的可读性和复用性。

打赏
评论区
头像
文章目录