引言:设计模式的重要性

设计模式是软件工程中的最佳实践,它们是经过时间考验的解决方案,用于解决在软件设计中反复出现的问题。在Python编程中,掌握设计模式不仅能提升代码质量,还能让你的程序更加灵活、可维护和可扩展。

为什么学习设计模式?

  1. 解决常见问题:设计模式提供了经过验证的解决方案
  2. 提高代码可读性:使用公认的设计模式使代码更易理解
  3. 促进团队协作:统一的设计语言便于团队沟通
  4. 提升架构能力:帮助开发者从更高层次思考软件设计

第一部分:设计模式基础

1.1 什么是设计模式?

设计模式是针对软件设计中常见问题的可重用解决方案。它们不是具体的代码,而是解决特定问题的通用模板。

1.2 Python与设计模式

Python的动态特性(如鸭子类型、装饰器、元类)使得某些设计模式的实现更加简洁优雅。但同时,Python的灵活性也要求我们更谨慎地选择何时使用设计模式。

1.3 23种经典设计模式分类

创建型模式(5种)

  • 单例模式(Singleton)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)
  • 建造者模式(Builder)
  • 原型模式(Prototype)

结构型模式(7种)

  • 适配器模式(Adapter)
  • 桥接模式(Bridge)
  • 组合模式(Composite)
  • 装饰器模式(Decorator)
  • 外观模式(Facade)
  • 享元模式(Flyweight)
  • 代理模式(Proxy)

行为型模式(11种)

  • 责任链模式(Chain of Responsibility)
  • 命令模式(Command)
  • 解释器模式(Interpreter)
  • 迭代器模式(Iterator)
  • 中介者模式(Mediator)
  • 备忘录模式(Memento)
  • 观察者模式(Observer)
  • 状态模式(State)
  • 策略模式(Strategy)
  • 模板方法模式(Template Method)
  • 访问者模式(Visitor)

第二部分:创建型模式详解

2.1 单例模式(Singleton)

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

Python实现

class Singleton: _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super().__new__(cls, *args, **kwargs) return cls._instance def __init__(self, value): if not hasattr(self, 'initialized'): self.value = value self.initialized = True # 使用示例 s1 = Singleton("First") s2 = Singleton("Second") print(s1 is s2) # True print(s1.value) # "First" (不会被"Second"覆盖) 

实际应用:数据库连接池、日志记录器、配置管理器。

Pythonic替代方案:使用模块级变量(Python模块本身就是单例)。

2.2 工厂方法模式(Factory Method)

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

Python实现

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!" 

实际应用:GUI组件创建、数据库连接创建、跨平台UI元素生成。

2.3 抽象工厂模式(Abstract Factory)

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

Python实现

from abc import ABC, abstractmethod # 抽象产品 class Button(ABC): @abstractmethod def paint(self): pass class Checkbox(ABC): @abstractmethod def paint(self): pass # 具体产品 class WinButton(Button): def paint(self): return "Render a Windows style button" class MacButton(Button): def paint(self): return "Render a Mac style button" class WinCheckbox(Checkbox): def paint(self): return "Render a Windows style checkbox" class MacCheckbox(Checkbox): def paint(self): return "Render a Mac style checkbox" # 抽象工厂 class GUIFactory(ABC): @abstractmethod def create_button(self): pass @abstractmethod def create_checkbox(self): pass # 具体工厂 class WinFactory(GUIFactory): def create_button(self): return WinButton() def create_checkbox(self): return WinCheckbox() class MacFactory(GUIFactory): def create_button(self): return MacButton() def create_checkbox(self): return MacCheckbox() # 使用示例 def client_code(factory: GUIFactory): button = factory.create_button() checkbox = factory.create_checkbox() print(button.paint()) print(checkbox.paint()) # 根据配置选择工厂 os_type = "Windows" # 可以从配置中获取 if os_type == "Windows": factory = WinFactory() elif os_type == "Mac": factory = MacFactory() else: raise ValueError("Unsupported OS") client_code(factory) 

实际应用:跨平台UI库、数据库访问层、主题系统。

2.4 建造者模式(Builder)

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

Python实现

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}GB, Storage={self.storage}GB, GPU={self.gpu}" class ComputerBuilder: def __init__(self): self.computer = Computer() def set_cpu(self, cpu): self.computer.cpu = cpu return self def set_ram(self, ram): self.computer.ram = ram return self def set_storage(self, storage): self.computer.storage = storage return self def set_gpu(self, gpu): self.computer.gpu = gpu return self def build(self): return self.computer # 使用示例 builder = ComputerBuilder() computer = (builder .set_cpu("Intel i7") .set_ram(16) .set_storage(512) .set_gpu("RTX 3060") .build()) print(computer) # 输出: Computer: CPU=Intel i7, RAM=16GB, Storage=512GB, GPU=RTX 3060 

实际应用:复杂对象构造(如订单系统、报表生成)、SQL查询构建器。

2.5 原型模式(Prototype)

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

Python实现

import copy class Prototype: def clone(self): return copy.deepcopy(self) class Document(Prototype): def __init__(self, title, content, author): self.title = title self.content = content self.author = author def __str__(self): return f"Document: {self.title} by {self.author}" # 使用示例 original = Document("Original", "This is the original content", "Alice") print(original) # Clone and modify clone1 = original.clone() clone1.title = "Clone 1" clone1.author = "Bob" print(clone1) # Another clone clone2 = original.clone() clone2.content = "Modified content" print(clone2) 

实际应用:游戏中的敌人生成、文档模板、配置对象的快速复制。

第三部分:结构型模式详解

3.1 适配器模式(Adapter)

意图:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

Python实现

# 目标接口 class Target: def request(self): return "Target: The default target's behavior." # 需要适配的类 class Adaptee: def specific_request(self): return "Adaptee: The specific request." # 适配器类 class Adapter(Target): def __init__(self, adaptee: Adaptee): self.adaptee = adaptee def request(self): return f"Adapter: (TRANSLATED) {self.adaptee.specific_request()}" # 使用示例 def client_code(target: Target): print(target.request()) # 没有适配器 adaptee = Adaptee() print("Client: I can work with the Target directly:") client_code(Target()) # 使用适配器 print("nClient: But I can't work with the Adaptee directly:") try: client_code(adaptee) except AttributeError: print("Error: Adaptee doesn't have request() method") print("nClient: But with the Adapter:") adapter = Adapter(adaptee) client_code(adapter) 

实际应用:整合旧系统、第三方库接口转换、API版本兼容。

3.2 桥接模式(Bridge)

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

Python实现

from abc import ABC, abstractmethod # 实现部分接口 class Color(ABC): @abstractmethod def fill(self): pass # 具体实现 class Red(Color): def fill(self): return "Red" class Green(Color): def fill(self): return "Green" class Blue(Color): def fill(self): return "Blue" # 抽象部分 class Shape(ABC): def __init__(self, color: Color): self.color = color @abstractmethod def draw(self): pass # 具体抽象 class Circle(Shape): def draw(self): return f"Circle with {self.color.fill()} color" class Square(Shape): def draw(self): return f"Square with {self.color.fill()} color" # 使用示例 red = Red() green = Green() blue = Blue() circle = Circle(red) square = Square(green) another_circle = Circle(blue) print(circle.draw()) # Circle with Red color print(square.draw()) # Square with Green color print(another_circle.draw()) # Circle with Blue color 

实际应用:GUI工具包(窗口和渲染器)、设备驱动程序、多维度分类系统。

3.3 组合模式(Composite)

意图:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

Python实现

from abc import ABC, abstractmethod # 组件接口 class Graphic(ABC): @abstractmethod def draw(self): pass @abstractmethod def add(self, graphic): pass @abstractmethod def remove(self, graphic): pass # 叶子节点 class Line(Graphic): def draw(self): return "Drawing a line" def add(self, graphic): raise NotImplementedError("Lines cannot have children") def remove(self, graphic): raise NotImplementedError("Lines cannot have children") class Circle(Graphic): def draw(self): return "Drawing a circle" def add(self, graphic): raise NotImplementedError("Circles cannot have children") def remove(self, graphic): raise NotImplementedError("Circles cannot have children") # 复合对象 class Picture(Graphic): def __init__(self): self.children = [] def draw(self): results = ["Drawing a picture:"] for child in self.children: results.append(f" {child.draw()}") return "n".join(results) def add(self, graphic): self.children.append(graphic) def remove(self, graphic): self.children.remove(graphic) # 使用示例 line1 = Line() circle1 = Circle() line2 = Line() picture1 = Picture() picture1.add(line1) picture1.add(circle1) picture2 = Picture() picture2.add(picture1) picture2.add(line2) print(picture2.draw()) 

实际应用:文件系统、图形用户界面、组织结构管理。

3.4 装饰器模式(Decorator)

意图:动态地给一个对象添加一些额外的职责。就扩展功能而言,它比生成子类更为灵活。

Python实现

from abc import ABC, abstractmethod # 组件接口 class Coffee(ABC): @abstractmethod def cost(self): pass @abstractmethod def description(self): pass # 具体组件 class SimpleCoffee(Coffee): def cost(self): return 5 def description(self): return "Simple coffee" # 装饰器基类 class CoffeeDecorator(Coffee): def __init__(self, coffee: Coffee): self._coffee = coffee def cost(self): return self._coffee.cost() def description(self): return self._coffee.description() # 具体装饰器 class MilkDecorator(CoffeeDecorator): def cost(self): return self._coffee.cost() + 2 def description(self): return self._coffee.description() + ", Milk" class SugarDecorator(CoffeeDecorator): def cost(self): return self._coffee.cost() + 1 def description(self): return self._coffee.description() + ", Sugar" class WhippedCreamDecorator(CoffeeDecorator): def cost(self): return self._coffee.cost() + 3 def description(self): return self._coffee.description() + ", Whipped Cream" # 使用示例 coffee = SimpleCoffee() print(f"{coffee.description()}: ${coffee.cost()}") coffee = MilkDecorator(coffee) print(f"{coffee.description()}: ${coffee.cost()}") coffee = SugarDecorator(coffee) print(f"{coffee.description()}: ${coffee.cost()}") coffee = WhippedCreamDecorator(coffee) print(f"{coffee.description()}: ${coffee.cost()}") 

实际应用:日志记录、性能监控、输入/输出流处理、Python装饰器语法。

3.5 外观模式(Facade)

意图:为子系统中的一组接口提供一个一致的界面。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

Python实现

# 子系统组件 class CPU: def start(self): return "CPU: Starting..." def execute(self): return "CPU: Executing instructions..." class Memory: def load(self): return "Memory: Loading data..." class HardDrive: def read(self): return "HardDrive: Reading data..." # 外观 class ComputerFacade: def __init__(self): self.cpu = CPU() self.memory = Memory() self.hard_drive = HardDrive() def start(self): results = [] results.append(self.hard_drive.read()) results.append(self.memory.load()) results.append(self.cpu.start()) results.append(self.cpu.execute()) return "n".join(results) # 使用示例 computer = ComputerFacade() print("Starting computer...") print(computer.start()) 

实际应用:简化复杂库的使用、启动/关闭系统、API网关。

3.6 享元模式(Flyweight)

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

Python实现

import random class Flyweight: def __init__(self, shared_state): self.shared_state = shared_state def operation(self, unique_state): s = str(self.shared_state) u = str(unique_state) return f"Flyweight: Shared [{s}], Unique [{u}]" class FlyweightFactory: def __init__(self): self.flyweights = {} def get_key(self, shared_state): return "_".join(sorted(shared_state)) def get_flyweight(self, shared_state): key = self.get_key(shared_state) if not self.flyweights.get(key): print(f"FlyweightFactory: Creating new flyweight for {key}") self.flyweights[key] = Flyweight(shared_state) else: print(f"FlyweightFactory: Reusing existing flyweight for {key}") return self.flyweights[key] def list_flyweights(self): count = len(self.flyweights) print(f"nFlyweightFactory: I have {count} flyweights:") for key in self.flyweights: print(f" {key}") def add_car_to_police_database(factory, plates, owner, brand, model, color): print("nClient: Adding a car to database.") flyweight = factory.get_flyweight([brand, model, color]) flyweight.operation([plates, owner]) # 使用示例 factory = FlyweightFactory() add_car_to_police_database(factory, "CL234", "James", "Chevrolet", "Camaro2018", "pink") add_car_to_police_database(factory, "CL234", "James", "Chevrolet", "Camaro2018", "pink") # Reuses add_car_to_police_database(factory, "CL235", "Mary", "Ferrari", "F8 Tributo", "red") add_car_to_police_database(factory, "CL236", "John", "BMW", "M5", "white") factory.list_flyweights() 

实际应用:文字处理软件中的字符对象、游戏中的粒子系统、数据库连接池。

3.7 代理模式(Proxy)

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

Python实现

from abc import ABC, abstractmethod import time # 主题接口 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: RealSubject): self._real_subject = real_subject self._access_control = None def check_access(self): # 简单的访问控制 self._access_control = True return self._access_control def log_access(self): print(f"Proxy: Log access at {time.time()}") def request(self): if not self.check_access(): return "Proxy: Access denied." self.log_access() if self._real_subject is None: self._real_subject = RealSubject() return f"Proxy: {self._real_subject.request()}" # 使用示例 def client_code(subject: Subject): print(subject.request()) print("Client: Executing with RealSubject:") real_subject = RealSubject() client_code(real_subject) print("nClient: Executing with Proxy:") proxy = Proxy(real_subject) client_code(proxy) 

实际应用:远程代理、保护代理、缓存代理、虚拟代理。

第四部分:行为型模式详解

4.1 责任链模式(Chain of Responsibility)

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

Python实现

from abc import ABC, abstractmethod class Handler(ABC): def __init__(self, successor=None): self.successor = successor def handle(self, request): handled = self.process_request(request) if not handled and self.successor: return self.successor.handle(request) return handled @abstractmethod def process_request(self, request): pass class ConcreteHandler1(Handler): def process_request(self, request): if 0 <= request < 10: return f"Handler1: I'll handle request {request}" return None class ConcreteHandler2(Handler): def process_request(self, request): if 10 <= request < 20: return f"Handler2: I'll handle request {request}" return None class ConcreteHandler3(Handler): def process_request(self, request): if 20 <= request < 30: return f"Handler3: I'll handle request {request}" return None # 使用示例 handler1 = ConcreteHandler1() handler2 = ConcreteHandler2() handler3 = ConcreteHandler3() handler1.successor = handler2 handler2.successor = handler3 requests = [5, 15, 25, 50] for request in requests: print(f"Client: Who can handle request {request}?") result = handler1.handle(request) if result: print(f" {result}") else: print(f" Request {request} was not handled.") 

实际应用:日志记录器、异常处理、审批流程、中间件。

4.2 命令模式(Command)

意图:将请求封装为对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

Python实现

from abc import ABC, abstractmethod # 命令接口 class Command(ABC): @abstractmethod def execute(self): pass @abstractmethod def undo(self): pass # 接收者 class Light: def on(self): return "Light is on" def off(self): return "Light is off" class Fan: def start(self): return "Fan is running" def stop(self): return "Fan is stopped" # 具体命令 class LightOnCommand(Command): def __init__(self, light: Light): self.light = light def execute(self): return self.light.on() def undo(self): return self.light.off() class FanStartCommand(Command): def __init__(self, fan: Fan): self.fan = fan def execute(self): return self.fan.start() def undo(self): return self.fan.stop() # 调用者 class RemoteControl: def __init__(self): self.history = [] def submit(self, command: Command): result = command.execute() self.history.append(command) return result def undo(self): if self.history: command = self.history.pop() return command.undo() return "Nothing to undo" # 使用示例 light = Light() fan = Fan() remote = RemoteControl() print(remote.submit(LightOnCommand(light))) print(remote.submit(FanStartCommand(fan))) print("nUndoing last command:") print(remote.undo()) # Fan stops print(remote.undo()) # Light turns off 

实际应用:GUI按钮和菜单项、事务系统、宏录制、任务队列。

4.3 解释器模式(Interpreter)

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

Python实现

from abc import ABC, abstractmethod # 抽象表达式 class Expression(ABC): @abstractmethod def interpret(self, context): pass # 终结符表达式 class Number(Expression): def __init__(self, value): self.value = value def interpret(self, context): return self.value # 非终结符表达式 class Add(Expression): def __init__(self, left: Expression, right: Expression): self.left = left self.right = right def interpret(self, context): return self.left.interpret(context) + self.right.interpret(context) class Subtract(Expression): def __init__(self, left: Expression, right: Expression): self.left = left self.right = right def interpret(self, context): return self.left.interpret(context) - self.right.interpret(context) # 上下文 class Context: def __init__(self): self.variables = {} def get(self, name): return self.variables.get(name) def set(self, name, value): self.variables[name] = value # 使用示例 # 构建表达式:(5 + 3) - 2 expression = Subtract( Add(Number(5), Number(3)), Number(2) ) result = expression.interpret(Context()) print(f"Result of (5 + 3) - 2 = {result}") 

实际应用:SQL解析、正则表达式、数学表达式求值、配置文件解析。

4.4 迭代器模式(Iterator)

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

Python实现

from collections.abc import Iterable, Iterator from typing import Any, List # Python内置支持迭代器模式 class Book: def __init__(self, title, author): self.title = title self.author = author def __str__(self): return f"'{self.title}' by {self.author}" class BookCollection(Iterable): def __init__(self): self.books: List[Book] = [] def add_book(self, book: Book): self.books.append(book) def __iter__(self): return BookIterator(self.books) class BookIterator(Iterator): def __init__(self, books: List[Book]): self.books = books self.position = 0 def __next__(self): if self.position < len(self.books): book = self.books[self.position] self.position += 1 return book raise StopIteration # 使用示例 collection = BookCollection() collection.add_book(Book("1984", "George Orwell")) collection.add_book(Book("To Kill a Mockingbird", "Harper Lee")) collection.add_book(Book("The Great Gatsby", "F. Scott Fitzgerald")) print("Book Collection:") for book in collection: print(f" {book}") 

实际应用:集合遍历、数据库游标、XML/JSON解析、自定义数据结构。

4.5 中介者模式(Mediator)

意图:定义一个对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

Python实现

from abc import ABC, abstractmethod class Mediator(ABC): @abstractmethod def notify(self, sender: object, event: str): pass class Component(ABC): def __init__(self, mediator: Mediator = None): self._mediator = mediator @property def mediator(self): return self._mediator @mediator.setter def mediator(self, mediator): self._mediator = mediator # 具体组件 class Button(Component): def click(self): self.mediator.notify(self, "click") def show(self): return "Button" class TextBox(Component): def __init__(self, mediator=None): super().__init__(mediator) self.text = "" def update_text(self, text): self.text = text self.mediator.notify(self, "text_change") def show(self): return f"TextBox: {self.text}" class ListBox(Component): def __init__(self, mediator=None): super().__init__(mediator) self.selection = "" def select(self, item): self.selection = item self.mediator.notify(self, "selection") def show(self): return f"ListBox: {self.selection}" # 具体中介者 class AuthenticationMediator(Mediator): def __init__(self): self.button = None self.text_box = None self.list_box = None def notify(self, sender: object, event: str): if event == "click" and sender == self.button: self.authenticate() elif event == "text_change" and sender == self.text_box: self.text_changed() elif event == "selection" and sender == self.list_box: self.selection_changed() def authenticate(self): print(f"Mediator: Authenticating user '{self.text_box.text}' with selection '{self.list_box.selection}'") # Authentication logic here def text_changed(self): if self.text_box.text: print("Mediator: Text entered, enabling button") else: print("Mediator: Text cleared, disabling button") def selection_changed(self): print(f"Mediator: Selection changed to '{self.list_box.selection}'") # 使用示例 mediator = AuthenticationMediator() button = Button(mediator) text_box = TextBox(mediator) list_box = ListBox(mediator) mediator.button = button mediator.text_box = text_box mediator.list_box = list_box # Simulate user interactions text_box.update_text("john_doe") list_box.select("Admin") button.click() 

实际应用:聊天室系统、表单验证、工作流协调、UI组件交互。

4.6 备忘录模式(Memento)

意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

Python实现

import datetime class Originator: def __init__(self, state): self._state = state print(f"Originator: My initial state is: {self._state}") def do_something(self): print("Originator: I'm doing something important.") self._state = self._generate_random_string(30) print(f"Originator: and my state has changed to: {self._state}") def _generate_random_string(self, length=10): import random import string return "".join(random.choices(string.ascii_letters + string.digits, k=length)) def save(self): return Memento(self._state) def restore(self, memento): self._state = memento.state print(f"Originator: My state has changed to: {self._state}") class Memento: def __init__(self, state): self._state = state self._date = str(datetime.datetime.now())[:19] @property def state(self): return self._state @property def date(self): return self._date class Caretaker: def __init__(self): self._mementos = [] def add_memento(self, memento): self._mementos.append(memento) def get_memento(self, index): return self._mementos[index] # 使用示例 originator = Originator("State A") caretaker = Caretaker() # Save state caretaker.add_memento(originator.save()) # Do some changes originator.do_something() # Save again caretaker.add_memento(originator.save()) # More changes originator.do_something() # Restore to first state print("nRestoring to first state...") originator.restore(caretaker.get_memento(0)) # Restore to second state print("nRestoring to second state...") originator.restore(caretaker.get_memento(1)) 

实际应用:撤销/重做功能、游戏存档、事务回滚、状态历史记录。

4.7 观察者模式(Observer)

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

Python实现

from abc import ABC, abstractmethod class Subject(ABC): @abstractmethod def attach(self, observer): pass @abstractmethod def detach(self, observer): pass @abstractmethod def notify(self): pass class Observer(ABC): @abstractmethod def update(self, subject: Subject): pass # 具体主题 class NewsPublisher(Subject): def __init__(self): self._observers = [] self._news = None def attach(self, observer): self._observers.append(observer) def detach(self, observer): self._observers.remove(observer) def notify(self): for observer in self._observers: observer.update(self) def add_news(self, news): self._news = news print(f"nNewsPublisher: New news added: {self._news}") self.notify() def get_news(self): return self._news # 具体观察者 class Subscriber(Observer): def __init__(self, name): self.name = name def update(self, subject: NewsPublisher): print(f"{self.name} received news: {subject.get_news()}") class SMSPublisher(Observer): def update(self, subject: NewsPublisher): print(f"SMS sent: Breaking news - {subject.get_news()}") # 使用示例 publisher = NewsPublisher() # Create subscribers bob = Subscriber("Bob") alice = Subscriber("Alice") sms = SMSPublisher() # Subscribe publisher.attach(bob) publisher.attach(alice) publisher.attach(sms) # Publish news publisher.add_news("Python 3.12 released!") # Unsubscribe one publisher.detach(alice) publisher.add_news("New design patterns book published!") 

实际应用:MVC架构、事件处理系统、消息队列、发布-订阅系统。

4.8 状态模式(State)

意图:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

Python实现

from abc import ABC, abstractmethod class State(ABC): @abstractmethod def handle(self, context): pass class Context: def __init__(self, state: State): self._state = state @property def state(self): return self._state @state.setter def state(self, state: State): print(f"Context: Transitioning to {type(state).__name__}") self._state = state def request(self): self._state.handle(self) # 具体状态 class ConcreteStateA(State): def handle(self, context): print("ConcreteStateA handles the request.") print("ConcreteStateA wants to change the state of the context.") context.state = ConcreteStateB() class ConcreteStateB(State): def handle(self, context): print("ConcreteStateB handles the request.") print("ConcreteStateB wants to change the state of the context.") context.state = ConcreteStateA() # 使用示例 context = Context(ConcreteStateA()) context.request() # State A handles, transitions to B context.request() # State B handles, transitions to A context.request() # State A handles, transitions to B 

实际应用:工作流系统、游戏状态管理、订单状态跟踪、UI状态机。

4.9 策略模式(Strategy)

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

Python实现

from abc import ABC, abstractmethod from typing import List class Strategy(ABC): @abstractmethod def do_algorithm(self, data: List[int]): pass class ConcreteStrategyA(Strategy): def do_algorithm(self, data: List[int]): return sorted(data) class ConcreteStrategyB(Strategy): def do_algorithm(self, data: List[int]): return sorted(data, reverse=True) class ConcreteStrategyC(Strategy): def do_algorithm(self, data: List[int]): return [x * 2 for x in data] class Context: def __init__(self, strategy: Strategy = None): self._strategy = strategy @property def strategy(self): return self._strategy @strategy.setter def strategy(self, strategy: Strategy): self._strategy = strategy def do_some_business_logic(self, data): print("Context: Sorting data using the strategy") result = self._strategy.do_algorithm(data) print(f"Result: {result}") # 使用示例 context = Context() print("Client: Strategy A") context.strategy = ConcreteStrategyA() context.do_some_business_logic([5, 2, 8, 1]) print("nClient: Strategy B") context.strategy = ConcreteStrategyB() context.do_some_business_logic([5, 2, 8, 1]) print("nClient: Strategy C") context.strategy = ConcreteStrategyC() context.do_some_business_logic([5, 2, 8, 1]) 

实际应用:排序算法、支付方式选择、压缩算法、验证策略。

4.10 模板方法模式(Template Method)

意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

Python实现

from abc import ABC, abstractmethod class AbstractClass(ABC): def template_method(self): self.base_operation1() self.required_operations1() self.base_operation2() self.hook1() self.required_operations2() self.base_operation3() self.hook2() def base_operation1(self): print("AbstractClass: I am doing the bulk of the work") def base_operation2(self): print("AbstractClass: But I let subclasses override some operations") def base_operation3(self): print("AbstractClass: But I am doing the bulk of the work anyway") @abstractmethod def required_operations1(self): pass @abstractmethod def required_operations2(self): pass def hook1(self): pass def hook2(self): pass class ConcreteClass1(AbstractClass): def required_operations1(self): print("ConcreteClass1: Implement Operation1") def required_operations2(self): print("ConcreteClass1: Implement Operation2") class ConcreteClass2(AbstractClass): def required_operations1(self): print("ConcreteClass2: Implement Operation1") def required_operations2(self): print("ConcreteClass2: Implement Operation2") def hook1(self): print("ConcreteClass2: Overridden Hook1") # 使用示例 print("Same client code can work with different subclasses:") client_code(ConcreteClass1()) print("nSame client code can work with different subclasses:") client_code(ConcreteClass2()) def client_code(abstract_class: AbstractClass): abstract_class.template_method() 

实际应用:框架设计、数据处理管道、测试框架、构建系统。

4.11 访问者模式(Visitor)

意图:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

Python实现

from abc import ABC, abstractmethod class Component(ABC): @abstractmethod def accept(self, visitor): pass class ConcreteComponentA(Component): def accept(self, visitor): visitor.visit_concrete_component_a(self) def operation_a(self): return "A" class ConcreteComponentB(Component): def accept(self, visitor): visitor.visit_concrete_component_b(self) def operation_b(self): return "B" class Visitor(ABC): @abstractmethod def visit_concrete_component_a(self, component: ConcreteComponentA): pass @abstractmethod def visit_concrete_component_b(self, component: ConcreteComponentB): pass class ConcreteVisitor1(Visitor): def visit_concrete_component_a(self, component: ConcreteComponentA): print(f"Visitor1: {component.operation_a()} + Visitor1") def visit_concrete_component_b(self, component: ConcreteComponentB): print(f"Visitor1: {component.operation_b()} + Visitor1") class ConcreteVisitor2(Visitor): def visit_concrete_component_a(self, component: ConcreteComponentA): print(f"Visitor2: {component.operation_a()} + Visitor2") def visit_concrete_component_b(self, component: ConcreteComponentB): print(f"Visitor2: {component.operation_b()} + Visitor2") # 使用示例 def client_code(components: list, visitor: Visitor): for component in components: component.accept(visitor) components = [ConcreteComponentA(), ConcreteComponentB()] print("The client code works with all visitors via the Visitor interface:") visitor1 = ConcreteVisitor1() client_code(components, visitor1) print("nIt allows the same client code to work with different types of visitors:") visitor2 = ConcreteVisitor2() client_code(components, visitor2) 

实际应用:编译器(语法树遍历)、文档处理、报表生成、对象结构操作。

第五部分:Python中的设计模式最佳实践

5.1 何时使用设计模式

  1. 识别问题:确认你遇到的问题是设计模式能解决的
  2. 评估复杂度:简单问题可能不需要模式
  3. 考虑团队:团队是否熟悉该模式
  4. 权衡成本:模式会增加复杂度,确保收益大于成本

5.2 Python特有的设计模式实现

Python的动态特性使得某些模式可以更简洁地实现:

装饰器模式的Pythonic实现

def bold_decorator(func): def wrapper(): return f"<b>{func()}</b>" return wrapper def italic_decorator(func): def wrapper(): return f"<i>{func()}</i>" return wrapper @bold_decorator @italic_decorator def hello(): return "Hello World" print(hello()) # <b><i>Hello World</i></b> 

单例模式的模块实现

# config.py class Config: def __init__(self): self.settings = {"debug": True} # 单例实例 instance = Config() # 使用时 from config import instance as config 

5.3 过度使用设计模式的陷阱

  1. YAGNI原则:You Aren’t Gonna Need It
  2. KISS原则:Keep It Simple, Stupid
  3. 模式不是目标:模式是手段,不是目的
  4. 避免模式强迫症:不要为了用模式而用模式

5.4 现代Python中的设计模式演变

  1. 数据类替代建造者:Python 3.7+的dataclasses
from dataclasses import dataclass @dataclass class Computer: cpu: str ram: int storage: int gpu: str = "Integrated" 
  1. 函数式编程影响:高阶函数、闭包
  2. 类型提示:使模式更清晰
  3. 异步编程:新的模式需求

第六部分:实战项目:设计模式综合应用

6.1 项目概述:电商订单处理系统

我们将构建一个综合使用多种设计模式的电商订单处理系统。

6.2 系统架构

用户 → 外观模式 → 订单系统 → 策略模式(支付) → 工厂模式(创建订单) → 观察者模式(通知) → 命令模式(处理) 

6.3 代码实现

from abc import ABC, abstractmethod from typing import List import datetime # ====== 创建型模式:工厂方法 ====== class Order(ABC): def __init__(self, items, customer): self.items = items self.customer = customer self.status = "Created" self.created_at = datetime.datetime.now() @abstractmethod def process(self): pass class PhysicalOrder(Order): def process(self): self.status = "Processing Physical Order" return f"Shipping {len(self.items)} items to {self.customer}" class DigitalOrder(Order): def process(self): self.status = "Processing Digital Order" return f"Generating license keys for {len(self.items)} items" class OrderFactory: @staticmethod def create_order(order_type, items, customer): if order_type == "physical": return PhysicalOrder(items, customer) elif order_type == "digital": return DigitalOrder(items, customer) else: raise ValueError(f"Unknown order type: {order_type}") # ====== 策略模式:支付方式 ====== class PaymentStrategy(ABC): @abstractmethod def pay(self, amount): pass class CreditCardPayment(PaymentStrategy): def __init__(self, card_number, cvv): self.card_number = card_number self.cvv = cvv def pay(self, amount): return f"Paid ${amount} using Credit Card {self.card_number[-4:]}" class PayPalPayment(PaymentStrategy): def __init__(self, email): self.email = email def pay(self, amount): return f"Paid ${amount} using PayPal account {self.email}" class CryptoPayment(PaymentStrategy): def __init__(self, wallet_address): self.wallet_address = wallet_address def pay(self, amount): return f"Paid ${amount} using Crypto wallet {self.wallet_address[:8]}..." # ====== 观察者模式:通知系统 ====== class OrderObserver(ABC): @abstractmethod def update(self, order: Order): pass class EmailNotifier(OrderObserver): def update(self, order): print(f"📧 Email sent to {order.customer}: Your order status is '{order.status}'") class SMSNotifier(OrderObserver): def update(self, order): print(f"📱 SMS sent to {order.customer}: Order status updated to '{order.status}'") class InventorySystem(OrderObserver): def update(self, order): print(f"📦 Inventory updated for {len(order.items)} items") class OrderSubject: def __init__(self): self._observers: List[OrderObserver] = [] def attach(self, observer: OrderObserver): self._observers.append(observer) def detach(self, observer: OrderObserver): self._observers.remove(observer) def notify(self, order: Order): for observer in self._observers: observer.update(order) # ====== 命令模式:订单处理 ====== class OrderCommand(ABC): @abstractmethod def execute(self): pass @abstractmethod def undo(self): pass class ProcessOrderCommand(OrderCommand): def __init__(self, order: Order, payment: PaymentStrategy, subject: OrderSubject): self.order = order self.payment = payment self.subject = subject self.executed = False def execute(self): if self.executed: return "Already executed" # Process payment payment_result = self.payment.pay(100) # Assume $100 total # Process order order_result = self.order.process() # Notify observers self.subject.notify(self.order) self.executed = True return f"{payment_result}n{order_result}" def undo(self): if not self.executed: return "Not executed yet" self.order.status = "Cancelled" self.executed = False return f"Order {self.order.__class__.__name__} cancelled" # ====== 外观模式:简化接口 ====== class OrderProcessingFacade: def __init__(self): self.observers = OrderSubject() # Setup default observers self.observers.attach(EmailNotifier()) self.observers.attach(SMSNotifier()) self.observers.attach(InventorySystem()) def process_order(self, order_type, items, customer, payment_type, payment_details): # Create order using factory order = OrderFactory.create_order(order_type, items, customer) # Create payment strategy if payment_type == "credit_card": payment = CreditCardPayment(payment_details["card"], payment_details["cvv"]) elif payment_type == "paypal": payment = PayPalPayment(payment_details["email"]) elif payment_type == "crypto": payment = CryptoPayment(payment_details["wallet"]) else: raise ValueError(f"Unknown payment type: {payment_type}") # Create and execute command command = ProcessOrderCommand(order, payment, self.observers) result = command.execute() return { "order": order, "command": command, "result": result } # ====== 使用示例 ====== def main(): print("=== E-commerce Order Processing System ===n") # Initialize facade facade = OrderProcessingFacade() # Scenario 1: Physical order with credit card print("1. Processing Physical Order with Credit Card:") result1 = facade.process_order( order_type="physical", items=["Laptop", "Mouse", "Keyboard"], customer="John Doe", payment_type="credit_card", payment_details={"card": "1234-5678-9012-3456", "cvv": "123"} ) print(result1["result"]) print() # Scenario 2: Digital order with PayPal print("2. Processing Digital Order with PayPal:") result2 = facade.process_order( order_type="digital", items=["Software License", "E-book"], customer="Jane Smith", payment_type="paypal", payment_details={"email": "jane@example.com"} ) print(result2["result"]) print() # Scenario 3: Undo last order print("3. Undoing last order:") undo_result = result2["command"].undo() print(undo_result) print() # Scenario 4: Custom observer print("4. Adding custom observer:") class AnalyticsTracker(OrderObserver): def update(self, order): print(f"📊 Analytics: Tracked order {order.__class__.__name__} for {order.customer}") facade.observers.attach(AnalyticsTracker()) result3 = facade.process_order( order_type="physical", items=["Monitor"], customer="Bob Johnson", payment_type="crypto", payment_details={"wallet": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"} ) print(result3["result"]) if __name__ == "__main__": main() 

6.4 运行结果示例

=== E-commerce Order Processing System === 1. Processing Physical Order with Credit Card: 📧 Email sent to John Doe: Your order status is 'Processing Physical Order' 📱 SMS sent to John Doe: Order status updated to 'Processing Physical Order' 📦 Inventory updated for 3 items Paid $100 using Credit Card 3456 Shipping 3 items to John Doe 2. Processing Digital Order with PayPal: 📧 Email sent to Jane Smith: Your order status is 'Processing Digital Order' 📱 SMS sent to Jane Smith: Order status updated to 'Processing Digital Order' 📦 Inventory updated for 2 items Paid $100 using PayPal account jane@example.com Generating license keys for 2 items 3. Undoing last order: Order DigitalOrder cancelled 4. Adding custom observer: 📧 Email sent to Bob Johnson: Your order status is 'Processing Physical Order' 📱 SMS sent to Bob Johnson: Order status updated to 'Processing Physical Order' 📦 Inventory updated for 1 items 📊 Analytics: Tracked order PhysicalOrder for Bob Johnson Paid $100 using Crypto wallet 0x742d35... Shipping 1 items to Bob Johnson 

第七部分:高级主题与最佳实践

7.1 设计模式与SOLID原则

SOLID原则是面向对象设计的五个基本原则,与设计模式密切相关:

  1. 单一职责原则(SRP):一个类应该只有一个改变的原因
  2. 开闭原则(OCP):对扩展开放,对修改关闭
  3. 里氏替换原则(LSP):子类应该能够替换父类
  4. 接口隔离原则(ISP):客户端不应该被迫依赖于它们不使用的接口
  5. 依赖倒置原则(DIP):高层模块不应该依赖于低层模块,两者都应该依赖于抽象

7.2 设计模式与代码重构

# 重构前:违反SRP和OCP class Report: def generate(self, data): # 生成报告 pass def save_to_pdf(self, report): # 保存为PDF pass def send_email(self, report, email): # 发送邮件 pass # 重构后:使用策略模式和装饰器模式 class ReportGenerator: def generate(self, data): return f"Report: {data}" class ReportSaver: def save(self, report, format): if format == "pdf": return f"PDF: {report}" elif format == "html": return f"HTML: {report}" class ReportSender: def send(self, report, email): return f"Sent to {email}: {report}" # 使用装饰器增强功能 def audit_log(func): def wrapper(*args, **kwargs): print(f"Audit: {func.__name__} called") return func(*args, **kwargs) return wrapper class AuditedReportSaver(ReportSaver): @audit_log def save(self, report, format): return super().save(report, format) 

7.3 测试设计模式

import unittest from unittest.mock import Mock class TestOrderSystem(unittest.TestCase): def test_strategy_pattern(self): # 测试策略模式 mock_payment = Mock() mock_payment.pay.return_value = "Success" context = Context(mock_payment) result = context.do_some_business_logic(100) mock_payment.pay.assert_called_once_with(100) self.assertEqual(result, "Success") def test_observer_pattern(self): # 测试观察者模式 subject = NewsPublisher() observer = Mock() subject.attach(observer) subject.add_news("Test News") observer.update.assert_called_once() 

7.4 性能考虑

  1. 避免过度抽象:简单的if-else可能比策略模式更高效
  2. 内存使用:享元模式可以节省内存,但增加了复杂度
  3. 创建开销:工厂模式可能增加对象创建时间
  4. 缓存:代理模式可以用于缓存结果

7.5 现代Python特性与设计模式

使用typing.Protocol(Python 3.8+)

from typing import Protocol class PaymentProtocol(Protocol): def pay(self, amount: float) -> str: ... def process_payment(payment: PaymentProtocol, amount: float): return payment.pay(amount) 

使用dataclasses简化模式

from dataclasses import dataclass from typing import List @dataclass class OrderItem: name: str price: float quantity: int @dataclass class Order: items: List[OrderItem] customer: str 

使用functools.partial

from functools import partial # 简单的工厂模式 def create_order_factory(order_type): if order_type == "physical": return partial(PhysicalOrder, items=[], customer="") return partial(DigitalOrder, items=[], customer="") 

第八部分:常见问题与解决方案

8.1 问题:我应该在项目中使用所有23种设计模式吗?

答案:绝对不应该!只在解决特定问题时使用合适的模式。简单项目可能只需要2-3种模式。

8.2 问题:设计模式会让代码变慢吗?

答案:通常影响微乎其微。现代硬件性能足够,代码可维护性比微小的性能差异更重要。但在性能关键路径上需要权衡。

8.3 问题:如何说服团队使用设计模式?

答案

  1. 从小处着手,展示实际好处
  2. 用代码审查和重构示例
  3. 强调长期维护成本
  4. 提供培训和文档

8.4 问题:Python的鸭子类型如何影响设计模式?

答案:鸭子类型让某些模式更灵活。例如,不需要严格的接口继承,只要对象有正确的方法即可工作。这减少了样板代码,但也要求更好的文档和测试。

8.5 问题:何时应该避免使用设计模式?

答案

  1. 原型或概念验证阶段
  2. 非常简单的脚本
  3. 性能极度敏感的代码
  4. 团队完全不熟悉模式时

第九部分:学习资源与进阶路径

9.1 推荐书籍

  • 《设计模式:可复用面向对象软件的基础》(GoF)
  • 《Head First设计模式》
  • 《Python高级编程》
  • 《架构整洁之道》

9.2 在线资源

  • Refactoring Guru(设计模式可视化解释)
  • Python官方文档
  • Real Python教程
  • Stack Overflow设计模式标签

9.3 实践建议

  1. 阅读开源项目:Django、Flask、Requests等
  2. 重构旧代码:在现有项目中识别模式
  3. 参与Code Review:学习他人如何使用模式
  4. 写博客:教是最好的学

9.4 进阶方向

  1. 架构模式:MVC、MVVM、微服务
  2. 并发模式:Actor、Reactors
  3. 函数式编程模式:Monad、Lens
  4. 领域驱动设计(DDD)

结论

设计模式是软件开发者的强大工具,但它们不是银弹。关键在于理解模式背后的思想,而不是死记硬背实现。

关键要点回顾:

  1. 理解意图:每个模式解决特定问题
  2. 掌握基础:23种模式分为三类
  3. Pythonic实现:利用语言特性简化模式
  4. 实践应用:通过项目巩固知识
  5. 持续学习:设计模式是永恒的话题

最后的建议:

  • 从简单开始:先掌握5-6个最常用的模式
  • 在实践中学习:不要只看书,要写代码
  • 保持好奇:探索模式的变体和组合
  • 注重平衡:模式是手段,不是目的

通过本教程的学习,你应该能够:

  • ✅ 理解23种设计模式的意图和结构
  • ✅ 在Python中实现这些模式
  • ✅ 识别何时使用哪种模式
  • ✅ 将模式应用到实际项目中
  • ✅ 与团队有效沟通设计决策

记住,最好的设计模式是那些让你的代码更清晰、更易维护、更易扩展的模式。祝你在设计模式的学习之旅中取得成功!