大数据

Python 23种设计模式

一、创建型模式 (5种)

1. 单例模式 (Singleton)

意图:确保一个类只有一个实例,并提供全局访问点。

class Singleton:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            print("Creating the singleton instance")
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance
    
    def show_message(self):
        print("Hello, I am a Singleton!")

# 使用示例
if __name__ == "__main__":
    # 创建单例对象
    singleton1 = Singleton()
    singleton1.show_message()
    
    # 再次获取实例,验证是否为同一个对象
    singleton2 = Singleton()
    singleton2.show_message()
    
    print(f"Is same instance? {singleton1 is singleton2}")

2. 工厂方法模式 (Factory Method)

意图:定义一个创建对象的接口,但让子类决定实例化哪个类。

from abc import ABC, abstractmethod

# 产品接口
class Product(ABC):
    @abstractmethod
    def use(self):
        pass

# 具体产品A
class ConcreteProductA(Product):
    def use(self):
        print("Using Product A")

# 具体产品B
class ConcreteProductB(Product):
    def use(self):
        print("Using Product B")

# 工厂接口
class Factory(ABC):
    @abstractmethod
    def create_product(self) -> Product:
        pass
    
    def some_operation(self):
        product = self.create_product()
        product.use()

# 具体工厂A
class ConcreteFactoryA(Factory):
    def create_product(self) -> Product:
        return ConcreteProductA()

# 具体工厂B
class ConcreteFactoryB(Factory):
    def create_product(self) -> Product:
        return ConcreteProductB()

# 使用示例
if __name__ == "__main__":
    factory_a = ConcreteFactoryA()
    factory_a.some_operation()
    
    factory_b = ConcreteFactoryB()
    factory_b.some_operation()

3. 抽象工厂模式 (Abstract Factory)

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

from abc import ABC, abstractmethod

# 抽象产品A
class AbstractProductA(ABC):
    @abstractmethod
    def use(self):
        pass

# 抽象产品B
class AbstractProductB(ABC):
    @abstractmethod
    def eat(self):
        pass

# 具体产品A1
class ProductA1(AbstractProductA):
    def use(self):
        print("Using Product A1")

# 具体产品A2
class ProductA2(AbstractProductA):
    def use(self):
        print("Using Product A2")

# 具体产品B1
class ProductB1(AbstractProductB):
    def eat(self):
        print("Eating Product B1")

# 具体产品B2
class ProductB2(AbstractProductB):
    def eat(self):
        print("Eating Product B2")

# 抽象工厂
class AbstractFactory(ABC):
    @abstractmethod
    def create_product_a(self) -> AbstractProductA:
        pass
    
    @abstractmethod
    def create_product_b(self) -> AbstractProductB:
        pass

# 具体工厂1
class ConcreteFactory1(AbstractFactory):
    def create_product_a(self) -> AbstractProductA:
        return ProductA1()
    
    def create_product_b(self) -> AbstractProductB:
        return ProductB1()

# 具体工厂2
class ConcreteFactory2(AbstractFactory):
    def create_product_a(self) -> AbstractProductA:
        return ProductA2()
    
    def create_product_b(self) -> AbstractProductB:
        return ProductB2()

# 使用示例
if __name__ == "__main__":
    factory1 = ConcreteFactory1()
    product_a1 = factory1.create_product_a()
    product_b1 = factory1.create_product_b()
    product_a1.use()
    product_b1.eat()
    
    factory2 = ConcreteFactory2()
    product_a2 = factory2.create_product_a()
    product_b2 = factory2.create_product_b()
    product_a2.use()
    product_b2.eat()

4. 建造者模式 (Builder)

意图:将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。

from abc import ABC, abstractmethod

# 产品类
class Computer:
    def __init__(self):
        self.cpu = None
        self.ram = None
        self.storage = None
        self.gpu = None
    
    def __str__(self):
        return f"Computer(cpu={self.cpu}, ram={self.ram}, storage={self.storage}, gpu={self.gpu})"

# 抽象建造者
class ComputerBuilder(ABC):
    @abstractmethod
    def build_cpu(self):
        pass
    
    @abstractmethod
    def build_ram(self):
        pass
    
    @abstractmethod
    def build_storage(self):
        pass
    
    @abstractmethod
    def build_gpu(self):
        pass
    
    @abstractmethod
    def get_computer(self) -> Computer:
        pass

# 具体建造者 - 游戏电脑
class GamingComputerBuilder(ComputerBuilder):
    def __init__(self):
        self.computer = Computer()
    
    def build_cpu(self):
        self.computer.cpu = "Intel i9"
    
    def build_ram(self):
        self.computer.ram = "32GB DDR4"
    
    def build_storage(self):
        self.computer.storage = "1TB SSD + 2TB HDD"
    
    def build_gpu(self):
        self.computer.gpu = "NVIDIA RTX 3080"
    
    def get_computer(self) -> Computer:
        return self.computer

# 具体建造者 - 办公电脑
class OfficeComputerBuilder(ComputerBuilder):
    def __init__(self):
        self.computer = Computer()
    
    def build_cpu(self):
        self.computer.cpu = "Intel i5"
    
    def build_ram(self):
        self.computer.ram = "16GB DDR4"
    
    def build_storage(self):
        self.computer.storage = "512GB SSD"
    
    def build_gpu(self):
        self.computer.gpu = "Integrated Graphics"
    
    def get_computer(self) -> Computer:
        return self.computer

# 指挥者
class ComputerDirector:
    def construct(self, builder: ComputerBuilder) -> Computer:
        builder.build_cpu()
        builder.build_ram()
        builder.build_storage()
        builder.build_gpu()
        return builder.get_computer()

# 使用示例
if __name__ == "__main__":
    director = ComputerDirector()
    
    # 构建游戏电脑
    gaming_builder = GamingComputerBuilder()
    gaming_computer = director.construct(gaming_builder)
    print("Gaming Computer:", gaming_computer)
    
    # 构建办公电脑
    office_builder = OfficeComputerBuilder()
    office_computer = director.construct(office_builder)
    print("Office Computer:", office_computer)

5. 原型模式 (Prototype)

意图:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

import copy
from abc import ABC, abstractmethod

# 抽象原型类
class Shape(ABC):
    def __init__(self):
        self.id = None
        self.type = None
    
    @abstractmethod
    def draw(self):
        pass
    
    def clone(self):
        return copy.deepcopy(self)
    
    def get_type(self):
        return self.type
    
    def get_id(self):
        return self.id
    
    def set_id(self, id):
        self.id = id

# 具体原型类 - 矩形
class Rectangle(Shape):
    def __init__(self):
        super().__init__()
        self.type = "Rectangle"
    
    def draw(self):
        print("Inside Rectangle::draw() method.")

# 具体原型类 - 圆形
class Circle(Shape):
    def __init__(self):
        super().__init__()
        self.type = "Circle"
    
    def draw(self):
        print("Inside Circle::draw() method.")

# 原型管理器
class ShapeCache:
    _shape_map = {}
    
    @classmethod
    def get_shape(cls, shape_id):
        cached_shape = cls._shape_map.get(shape_id)
        return cached_shape.clone()
    
    @classmethod
    def load_cache(cls):
        circle = Circle()
        circle.set_id("1")
        cls._shape_map[circle.get_id()] = circle
        
        rectangle = Rectangle()
        rectangle.set_id("2")
        cls._shape_map[rectangle.get_id()] = rectangle

# 使用示例
if __name__ == "__main__":
    ShapeCache.load_cache()
    
    cloned_shape1 = ShapeCache.get_shape("1")
    print("Shape:", cloned_shape1.get_type())
    cloned_shape1.draw()
    
    cloned_shape2 = ShapeCache.get_shape("2")
    print("Shape:", cloned_shape2.get_type())
    cloned_shape2.draw()
    
    # 验证是否为不同对象
    print("Are shapes same?", cloned_shape1 is cloned_shape2)

二、结构型模式 (7种)

6. 适配器模式 (Adapter)

意图:将一个类的接口转换成客户希望的另外一个接口。

from abc import ABC, abstractmethod

# 目标接口
class MediaPlayer(ABC):
    @abstractmethod
    def play(self, audio_type: str, file_name: str):
        pass

# 适配者接口
class AdvancedMediaPlayer(ABC):
    @abstractmethod
    def play_vlc(self, file_name: str):
        pass
    
    @abstractmethod
    def play_mp4(self, file_name: str):
        pass

# 具体适配者 - VLC播放器
class VlcPlayer(AdvancedMediaPlayer):
    def play_vlc(self, file_name: str):
        print(f"Playing vlc file. Name: {file_name}")
    
    def play_mp4(self, file_name: str):
        pass

# 具体适配者 - MP4播放器
class Mp4Player(AdvancedMediaPlayer):
    def play_vlc(self, file_name: str):
        pass
    
    def play_mp4(self, file_name: str):
        print(f"Playing mp4 file. Name: {file_name}")

# 适配器类
class MediaAdapter(MediaPlayer):
    def __init__(self, audio_type: str):
        if audio_type.lower() == "vlc":
            self.advanced_music_player = VlcPlayer()
        elif audio_type.lower() == "mp4":
            self.advanced_music_player = Mp4Player()
    
    def play(self, audio_type: str, file_name: str):
        if audio_type.lower() == "vlc":
            self.advanced_music_player.play_vlc(file_name)
        elif audio_type.lower() == "mp4":
            self.advanced_music_player.play_mp4(file_name)

# 具体目标类 - 音频播放器
class AudioPlayer(MediaPlayer):
    def play(self, audio_type: str, file_name: str):
        if audio_type.lower() == "mp3":
            print(f"Playing mp3 file. Name: {file_name}")
        elif audio_type.lower() in ("vlc", "mp4"):
            media_adapter = MediaAdapter(audio_type)
            media_adapter.play(audio_type, file_name)
        else:
            print(f"Invalid media. {audio_type} format not supported")

# 使用示例
if __name__ == "__main__":
    audio_player = AudioPlayer()
    
    audio_player.play("mp3", "beyond the horizon.mp3")
    audio_player.play("mp4", "alone.mp4")
    audio_player.play("vlc", "far far away.vlc")
    audio_player.play("avi", "mind me.avi")

7. 桥接模式 (Bridge)

意图:将抽象部分与实现部分分离,使它们都可以独立地变化。

from abc import ABC, abstractmethod

# 实现部分接口
class DrawAPI(ABC):
    @abstractmethod
    def draw_circle(self, radius: int, x: int, y: int):
        pass

# 具体实现A
class RedCircle(DrawAPI):
    def draw_circle(self, radius: int, x: int, y: int):
        print(f"Drawing Circle[ color: red, radius: {radius}, x: {x}, y: {y}]")

# 具体实现B
class GreenCircle(DrawAPI):
    def draw_circle(self, radius: int, x: int, y: int):
        print(f"Drawing Circle[ color: green, radius: {radius}, x: {x}, y: {y}]")

# 抽象部分
class Shape:
    def __init__(self, draw_api: DrawAPI):
        self.draw_api = draw_api
    
    def draw(self):
        pass

# 扩展抽象部分 - 圆形
class Circle(Shape):
    def __init__(self, x: int, y: int, radius: int, draw_api: DrawAPI):
        super().__init__(draw_api)
        self.x = x
        self.y = y
        self.radius = radius
    
    def draw(self):
        self.draw_api.draw_circle(self.radius, self.x, self.y)

# 使用示例
if __name__ == "__main__":
    red_circle = Circle(100, 100, 10, RedCircle())
    green_circle = Circle(200, 200, 20, GreenCircle())
    
    red_circle.draw()
    green_circle.draw()

8. 组合模式 (Composite)

意图:将对象组合成树形结构以表示"部分-整体"的层次结构

from abc import ABC, abstractmethod
from typing import List

# 组件接口
class Employee(ABC):
    @abstractmethod
    def show_employee_details(self):
        pass

# 叶子节点 - 开发人员
class Developer(Employee):
    def __init__(self, name: str, position: str):
        self.name = name
        self.position = position
    
    def show_employee_details(self):
        print(f"Developer: {self.name}, Position: {self.position}")

# 叶子节点 - 经理
class Manager(Employee):
    def __init__(self, name: str, position: str):
        self.name = name
        self.position = position
    
    def show_employee_details(self):
        print(f"Manager: {self.name}, Position: {self.position}")

# 组合类 - 部门
class Department(Employee):
    def __init__(self, name: str):
        self.name = name
        self.employees: List[Employee] = []
    
    def add_employee(self, employee: Employee):
        self.employees.append(employee)
    
    def remove_employee(self, employee: Employee):
        self.employees.remove(employee)
    
    def show_employee_details(self):
        print(f"Department: {self.name}")
        for employee in self.employees:
            employee.show_employee_details()

# 使用示例
if __name__ == "__main__":
    dev1 = Developer("John", "Senior Developer")
    dev2 = Developer("David", "Junior Developer")
    
    engineering = Department("Engineering")
    engineering.add_employee(dev1)
    engineering.add_employee(dev2)
    
    man1 = Manager("Mike", "Engineering Manager")
    man2 = Manager("Sophia", "HR Manager")
    
    hr = Department("Human Resources")
    hr.add_employee(man2)
    
    company = Department("Company")
    company.add_employee(man1)
    company.add_employee(engineering)
    company.add_employee(hr)
    
    company.show_employee_details()

9. 装饰器模式 (Decorator)

意图:动态地给一个对象添加一些额外的职责。

from abc import ABC, abstractmethod

# 组件接口
class Car(ABC):
    @abstractmethod
    def assemble(self):
        pass

# 具体组件
class BasicCar(Car):
    def assemble(self):
        print("Basic Car.")

# 装饰器抽象类
class CarDecorator(Car):
    def __init__(self, car: Car):
        self.car = car
    
    def assemble(self):
        self.car.assemble()

# 具体装饰器 - 运动型
class SportsCar(CarDecorator):
    def assemble(self):
        super().assemble()
        print("Adding features of Sports Car.")

# 具体装饰器 - 豪华型
class LuxuryCar(CarDecorator):
    def assemble(self):
        super().assemble()
        print("Adding features of Luxury Car.")

# 使用示例
if __name__ == "__main__":
    sports_car = SportsCar(BasicCar())
    sports_car.assemble()
    print()
    
    sports_luxury_car = SportsCar(LuxuryCar(BasicCar()))
    sports_luxury_car.assemble()

10. 外观模式 (Facade)

意图:为子系统中的一组接口提供一个一致的界面。

# 子系统A
class CPU:
    def freeze(self):
        print("CPU freeze")
    
    def jump(self, position: int):
        print(f"CPU jump to {position}")
    
    def execute(self):
        print("CPU execute")

# 子系统B
class Memory:
    def load(self, position: int, data: str):
        print(f"Memory load at {position}")

# 子系统C
class HardDrive:
    def read(self, lba: int, size: int) -> str:
        print(f"HardDrive read {size} bytes from {lba}")
        return "data"

# 外观类
class ComputerFacade:
    BOOT_ADDRESS = 0x00000000
    BOOT_SECTOR = 0x00000000
    SECTOR_SIZE = 512
    
    def __init__(self):
        self.processor = CPU()
        self.ram = Memory()
        self.hd = HardDrive()
    
    def start(self):
        self.processor.freeze()
        self.ram.load(self.BOOT_ADDRESS, self.hd.read(self.BOOT_SECTOR, self.SECTOR_SIZE))
        self.processor.jump(self.BOOT_ADDRESS)
        self.processor.execute()

# 使用示例
if __name__ == "__main__":
    computer = ComputerFacade()
    computer.start()

11. 享元模式 (Flyweight)

意图:运用共享技术有效地支持大量细粒度的对象。

import random
from typing import Dict

# 享元接口
class Shape:
    def draw(self, x: int, y: int, radius: int):
        pass

# 具体享元类
class Circle(Shape):
    def __init__(self, color: str):
        self.color = color
    
    def draw(self, x: int, y: int, radius: int):
        print(f"Circle: Draw() [Color: {self.color}, x: {x}, y: {y}, radius: {radius}]")

# 享元工厂
class ShapeFactory:
    _circle_map: Dict[str, Circle] = {}
    
    @classmethod
    def get_circle(cls, color: str) -> Circle:
        circle = cls._circle_map.get(color)
        
        if circle is None:
            circle = Circle(color)
            cls._circle_map[color] = circle
            print(f"Creating circle of color: {color}")
        
        return circle

# 使用示例
if __name__ == "__main__":
    colors = ["Red", "Green", "Blue", "White", "Black"]
    
    for _ in range(20):
        circle = ShapeFactory.get_circle(random.choice(colors))
        circle.draw(random.randint(0, 100), random.randint(0, 100), 100)

12. 代理模式 (Proxy)

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

from abc import ABC, abstractmethod

# 接口
class Image(ABC):
    @abstractmethod
    def display(self):
        pass

# 真实对象
class RealImage(Image):
    def __init__(self, file_name: str):
        self.file_name = file_name
        self._load_from_disk()
    
    def _load_from_disk(self):
        print(f"Loading {self.file_name}")
    
    def display(self):
        print(f"Displaying {self.file_name}")

# 代理类
class ProxyImage(Image):
    def __init__(self, file_name: str):
        self.file_name = file_name
        self.real_image = None
    
    def display(self):
        if self.real_image is None:
            self.real_image = RealImage(self.file_name)
        self.real_image.display()

# 使用示例
if __name__ == "__main__":
    image = ProxyImage("test_10mb.jpg")
    
    # 图像将从磁盘加载
    image.display()
    print()
    
    # 图像不需要从磁盘加载
    image.display()

三、行为型模式 (11种)

13. 责任链模式 (Chain of Responsibility)

意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系

from abc import ABC, abstractmethod

# 抽象处理器
class Logger(ABC):
    INFO = 1
    DEBUG = 2
    ERROR = 3
    
    def __init__(self, level: int):
        self.level = level
        self.next_logger = None
    
    def set_next_logger(self, next_logger):
        self.next_logger = next_logger
    
    def log_message(self, level: int, message: str):
        if self.level <= level:
            self.write(message)
        
        if self.next_logger is not None:
            self.next_logger.log_message(level, message)
    
    @abstractmethod
    def write(self, message: str):
        pass

# 具体处理器 - 控制台日志
class ConsoleLogger(Logger):
    def write(self, message: str):
        print(f"Standard Console::Logger: {message}")

# 具体处理器 - 错误日志
class ErrorLogger(Logger):
    def write(self, message: str):
        print(f"Error Console::Logger: {message}")

# 具体处理器 - 文件日志
class FileLogger(Logger):
    def write(self, message: str):
        print(f"File::Logger: {message}")

# 使用示例
if __name__ == "__main__":
    def get_chain_of_loggers() -> Logger:
        error_logger = ErrorLogger(Logger.ERROR)
        file_logger = FileLogger(Logger.DEBUG)
        console_logger = ConsoleLogger(Logger.INFO)
        
        error_logger.set_next_logger(file_logger)
        file_logger.set_next_logger(console_logger)
        
        return error_logger
    
    logger_chain = get_chain_of_loggers()
    
    logger_chain.log_message(Logger.INFO, "This is an information.")
    print()
    
    logger_chain.log_message(Logger.DEBUG, "This is a debug level information.")
    print()
    
    logger_chain.log_message(Logger.ERROR, "This is an error information.")

14. 命令模式 (Command)

意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。

from abc import ABC, abstractmethod
from typing import List

# 命令接口
class Order(ABC):
    @abstractmethod
    def execute(self):
        pass

# 请求类
class Stock:
    def __init__(self):
        self.name = "ABC"
        self.quantity = 10
    
    def buy(self):
        print(f"Stock [ Name: {self.name}, Quantity: {self.quantity} ] bought")
    
    def sell(self):
        print(f"Stock [ Name: {self.name}, Quantity: {self.quantity} ] sold")

# 具体命令 - 买入
class BuyStock(Order):
    def __init__(self, stock: Stock):
        self.stock = stock
    
    def execute(self):
        self.stock.buy()

# 具体命令 - 卖出
class SellStock(Order):
    def __init__(self, stock: Stock):
        self.stock = stock
    
    def execute(self):
        self.stock.sell()

# 调用者
class Broker:
    def __init__(self):
        self.order_list: List[Order] = []
    
    def take_order(self, order: Order):
        self.order_list.append(order)
    
    def place_orders(self):
        for order in self.order_list:
            order.execute()
        self.order_list.clear()

# 使用示例
if __name__ == "__main__":
    abc_stock = Stock()
    
    buy_stock_order = BuyStock(abc_stock)
    sell_stock_order = SellStock(abc_stock)
    
    broker = Broker()
    broker.take_order(buy_stock_order)
    broker.take_order(sell_stock_order)
    
    broker.place_orders()

15. 解释器模式 (Interpreter)

意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

from abc import ABC, abstractmethod

# 表达式接口
class Expression(ABC):
    @abstractmethod
    def interpret(self, context: str) -> bool:
        pass

# 终结符表达式
class TerminalExpression(Expression):
    def __init__(self, data: str):
        self.data = data
    
    def interpret(self, context: str) -> bool:
        return self.data in context

# 或表达式
class OrExpression(Expression):
    def __init__(self, expr1: Expression, expr2: Expression):
        self.expr1 = expr1
        self.expr2 = expr2
    
    def interpret(self, context: str) -> bool:
        return self.expr1.interpret(context) or self.expr2.interpret(context)

# 与表达式
class AndExpression(Expression):
    def __init__(self, expr1: Expression, expr2: Expression):
        self.expr1 = expr1
        self.expr2 = expr2
    
    def interpret(self, context: str) -> bool:
        return self.expr1.interpret(context) and self.expr2.interpret(context)

# 使用示例
if __name__ == "__main__":
    # 规则:Robert 和 John 是男性
    def get_male_expression() -> Expression:
        robert = TerminalExpression("Robert")
        john = TerminalExpression("John")
        return OrExpression(robert, john)
    
    # 规则:Julie 是一个已婚的女性
    def get_married_woman_expression() -> Expression:
        julie = TerminalExpression("Julie")
        married = TerminalExpression("Married")
        return AndExpression(julie, married)
    
    is_male = get_male_expression()
    is_married_woman = get_married_woman_expression()
    
    print("John is male?", is_male.interpret("John"))
    print("Julie is a married woman?", is_married_woman.interpret("Married Julie"))

16. 迭代器模式 (Iterator)

意图:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

from abc import ABC, abstractmethod
from typing import List

# 迭代器接口
class Iterator(ABC):
    @abstractmethod
    def has_next(self) -> bool:
        pass
    
    @abstractmethod
    def next(self):
        pass

# 容器接口
class Container(ABC):
    @abstractmethod
    def get_iterator(self) -> Iterator:
        pass

# 具体容器
class NameRepository(Container):
    def __init__(self):
        self.names = ["Robert", "John", "Julie", "Lora"]
    
    def get_iterator(self) -> Iterator:
        return NameIterator(self)

# 具体迭代器
class NameIterator(Iterator):
    def __init__(self, repository: NameRepository):
        self.repository = repository
        self.index = 0
    
    def has_next(self) -> bool:
        return self.index < len(self.repository.names)
    
    def next(self):
        if self.has_next():
            item = self.repository.names[self.index]
            self.index += 1
            return item
        return None

# 使用示例
if __name__ == "__main__":
    names_repository = NameRepository()
    iterator = names_repository.get_iterator()
    
    while iterator.has_next():
        name = iterator.next()
        print(f"Name: {name}")

17. 中介者模式 (Mediator)

意图:用一个中介对象来封装一系列的对象交互。

from abc import ABC, abstractmethod
from datetime import datetime

# 中介者接口
class ChatRoomMediator(ABC):
    @abstractmethod
    def show_message(self, user, message: str):
        pass

# 具体中介者
class ChatRoom(ChatRoomMediator):
    def show_message(self, user, message: str):
        time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        sender = user.name
        print(f"{time} [{sender}]: {message}")

# 同事类
class User:
    def __init__(self, name: str, chat_room: ChatRoomMediator):
        self.name = name
        self.chat_room = chat_room
    
    def send_message(self, message: str):
        self.chat_room.show_message(self, message)

# 使用示例
if __name__ == "__main__":
    chat_room = ChatRoom()
    
    john = User("John", chat_room)
    jane = User("Jane", chat_room)
    
    john.send_message("Hi there!")
    jane.send_message("Hey!")

18. 备忘录模式 (Memento)

意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

# 备忘录类
class Memento:
    def __init__(self, state: str):
        self.state = state
    
    def get_state(self) -> str:
        return self.state

# 原发器类
class Originator:
    def __init__(self):
        self.state = None
    
    def set_state(self, state: str):
        self.state = state
    
    def get_state(self) -> str:
        return self.state
    
    def save_state_to_memento(self) -> Memento:
        return Memento(self.state)
    
    def get_state_from_memento(self, memento: Memento):
        self.state = memento.get_state()

# 管理者类
class CareTaker:
    def __init__(self):
        self.memento_list: List[Memento] = []
    
    def add(self, state: Memento):
        self.memento_list.append(state)
    
    def get(self, index: int) -> Memento:
        return self.memento_list[index]

# 使用示例
if __name__ == "__main__":
    originator = Originator()
    care_taker = CareTaker()
    
    originator.set_state("State #1")
    originator.set_state("State #2")
    care_taker.add(originator.save_state_to_memento())
    
    originator.set_state("State #3")
    care_taker.add(originator.save_state_to_memento())
    
    originator.set_state("State #4")
    print("Current State:", originator.get_state())
    
    originator.get_state_from_memento(care_taker.get(0))
    print("First saved State:", originator.get_state())
    
    originator.get_state_from_memento(care_taker.get(1))
    print("Second saved State:", originator.get_state())

19. 观察者模式 (Observer)

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

from abc import ABC, abstractmethod
from typing import List

# 主题接口
class Subject(ABC):
    @abstractmethod
    def register_observer(self, observer):
        pass
    
    @abstractmethod
    def remove_observer(self, observer):
        pass
    
    @abstractmethod
    def notify_observers(self):
        pass

# 具体主题
class ConcreteSubject(Subject):
    def __init__(self):
        self.observers: List[Observer] = []
        self.state = None
    
    def register_observer(self, observer):
        self.observers.append(observer)
    
    def remove_observer(self, observer):
        self.observers.remove(observer)
    
    def notify_observers(self):
        for observer in self.observers:
            observer.update()
    
    def get_state(self):
        return self.state
    
    def set_state(self, state):
        self.state = state
        self.notify_observers()

# 观察者接口
class Observer(ABC):
    @abstractmethod
    def update(self):
        pass

# 具体观察者A
class ConcreteObserverA(Observer):
    def __init__(self, subject: ConcreteSubject):
        self.subject = subject
        self.subject.register_observer(self)
    
    def update(self):
        print(f"ConcreteObserverA: Subject's state changed to {self.subject.get_state()}")

# 具体观察者B
class ConcreteObserverB(Observer):
    def __init__(self, subject: ConcreteSubject):
        self.subject = subject
        self.subject.register_observer(self)
    
    def update(self):
        print(f"ConcreteObserverB: Subject's state changed to {self.subject.get_state()}")

# 使用示例
if __name__ == "__main__":
    subject = ConcreteSubject()
    
    ConcreteObserverA(subject)
    ConcreteObserverB(subject)
    
    subject.set_state(1)
    subject.set_state(2)

20. 状态模式 (State)

意图:允许一个对象在其内部状态改变时改变它的行为

from abc import ABC, abstractmethod

# 状态接口
class State(ABC):
    @abstractmethod
    def do_action(self, context):
        pass

# 具体状态 - 开始状态
class StartState(State):
    def do_action(self, context):
        print("Player is in start state")
        context.state = self
    
    def __str__(self):
        return "Start State"

# 具体状态 - 停止状态
class StopState(State):
    def do_action(self, context):
        print("Player is in stop state")
        context.state = self
    
    def __str__(self):
        return "Stop State"

# 上下文类
class Context:
    def __init__(self):
        self.state = None
    
    def set_state(self, state: State):
        self.state = state
    
    def get_state(self) -> State:
        return self.state

# 使用示例
if __name__ == "__main__":
    context = Context()
    
    start_state = StartState()
    start_state.do_action(context)
    print(context.get_state())
    
    stop_state = StopState()
    stop_state.do_action(context)
    print(context.get_state())

21. 策略模式 (Strategy)

意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

from abc import ABC, abstractmethod

# 策略接口
class Strategy(ABC):
    @abstractmethod
    def do_operation(self, num1: int, num2: int) -> int:
        pass

# 具体策略 - 加法
class OperationAdd(Strategy):
    def do_operation(self, num1: int, num2: int) -> int:
        return num1 + num2

# 具体策略 - 减法
class OperationSubtract(Strategy):
    def do_operation(self, num1: int, num2: int) -> int:
        return num1 - num2

# 具体策略 - 乘法
class OperationMultiply(Strategy):
    def do_operation(self, num1: int, num2: int) -> int:
        return num1 * num2

# 上下文类
class Context:
    def __init__(self, strategy: Strategy):
        self.strategy = strategy
    
    def execute_strategy(self, num1: int, num2: int) -> int:
        return self.strategy.do_operation(num1, num2)

# 使用示例
if __name__ == "__main__":
    context = Context(OperationAdd())
    print("10 + 5 =", context.execute_strategy(10, 5))
    
    context = Context(OperationSubtract())
    print("10 - 5 =", context.execute_strategy(10, 5))
    
    context = Context(OperationMultiply())
    print("10 * 5 =", context.execute_strategy(10, 5))

22. 模板方法模式 (Template Method)

意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

from abc import ABC, abstractmethod

# 抽象类 - 定义模板方法
class Game(ABC):
    def play(self):
        # 初始化游戏
        self.initialize()
        
        # 开始游戏
        self.start_play()
        
        # 结束游戏
        self.end_play()
    
    @abstractmethod
    def initialize(self):
        pass
    
    @abstractmethod
    def start_play(self):
        pass
    
    @abstractmethod
    def end_play(self):
        pass

# 具体子类 - 足球游戏
class Football(Game):
    def initialize(self):
        print("Football Game Initialized! Start playing.")
    
    def start_play(self):
        print("Football Game Started. Enjoy the game!")
    
    def end_play(self):
        print("Football Game Finished!")

# 具体子类 - 篮球游戏
class Basketball(Game):
    def initialize(self):
        print("Basketball Game Initialized! Start playing.")
    
    def start_play(self):
        print("Basketball Game Started. Enjoy the game!")
    
    def end_play(self):
        print("Basketball Game Finished!")

# 使用示例
if __name__ == "__main__":
    game = Football()
    game.play()
    print()
    
    game = Basketball()
    game.play()

23. 访问者模式 (Visitor)

意图:表示一个作用于某对象结构中的各元素的操作。

from abc import ABC, abstractmethod

# 元素接口
class ComputerPart(ABC):
    @abstractmethod
    def accept(self, visitor):
        pass

# 具体元素 - 键盘
class Keyboard(ComputerPart):
    def accept(self, visitor):
        visitor.visit(self)

# 具体元素 - 显示器
class Monitor(ComputerPart):
    def accept(self, visitor):
        visitor.visit(self)

# 具体元素 - 鼠标
class Mouse(ComputerPart):
    def accept(self, visitor):
        visitor.visit(self)

# 具体元素 - 计算机
class Computer(ComputerPart):
    def __init__(self):
        self.parts = [Mouse(), Keyboard(), Monitor()]
    
    def accept(self, visitor):
        for part in self.parts:
            part.accept(visitor)
        visitor.visit(self)

# 访问者接口
class ComputerPartVisitor(ABC):
    @abstractmethod
    def visit(self, computer):
        pass
    
    @abstractmethod
    def visit(self, mouse):
        pass
    
    @abstractmethod
    def visit(self, keyboard):
        pass
    
    @abstractmethod
    def visit(self, monitor):
        pass

# 具体访问者 - 显示访问者
class ComputerPartDisplayVisitor(ComputerPartVisitor):
    def visit(self, computer):
        print("Displaying Computer.")
    
    def visit(self, mouse):
        print("Displaying Mouse.")
    
    def visit(self, keyboard):
        print("Displaying Keyboard.")
    
    def visit(self, monitor):
        print("Displaying Monitor.")

# 使用示例
if __name__ == "__main__":
    computer = Computer()
    computer.accept(ComputerPartDisplayVisitor())

总结

这23种设计模式可以分为三大类:

  1. 创建型模式:关注对象的创建过程
    • 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
  2. 结构型模式:关注类和对象的组合
    • 适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式
  3. 行为型模式:关注对象之间的交互
    • 责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

每种设计模式都有其特定的应用场景,理解这些模式可以帮助我们编写更加灵活、可维护和可扩展的代码。在实际开发中,应根据具体问题选择合适的模式,而不是为了使用模式而使用模式。