从“化合物”到“元素”:用 Python 读懂《元素模式》的 16 种基础设计模式
引言:为什么需要“元素模式”?
经典 GoF 的 23 种设计模式,常被比作软件设计中的“化合物”:它们功能明确、组合复杂,但也容易让初学者觉得抽象、难以落地。Jason McC. Smith 在《Elemental Design Patterns》中提出了一个更底层的视角:把设计模式拆解成更小、更基础、可组合的“元素”。
作者将对象、字段、方法、类型四个维度构成的设计空间,对应到 (2^4=16) 个基本坐标点,形成了 16 种元素模式(Elemental Design Patterns, EDP)。它们不是要替代 GoF 模式,而是为理解、比较和组合设计模式提供一套“化学元素表”。
本文用 Python 逐一介绍这 16 种元素模式。代码不是模板,而是为了说明:这些模式描述的是对象之间的基本关系与方法调用结构。
16 种元素模式总览
| 序号 | 模式 | 核心关系 |
|---|---|---|
| 1 | 创建对象 Create Object | 实例化对象 |
| 2 | 检索 Retrieve | 读取字段/属性 |
| 3 | 继承 Inheritance | 类型之间的继承关系 |
| 4 | 抽象接口 Abstract Interface | 定义统一接口 |
| 5 | 委托 Delegation | 把职责转交给另一个对象 |
| 6 | 重定向 Redirection | 不同对象间调用同名方法 |
| 7 | 集聚 Conglomeration | 同一对象内部方法聚集调用 |
| 8 | 递归 Recursion | 同一对象同一方法调用自身 |
| 9 | 归复方法 Revert Method | 操作后恢复状态/反向逻辑 |
| 10 | 扩展方法 Extend Method | 不修改原类而增加方法 |
| 11 | 委托型集聚 Delegated Conglomeration | 集聚过程中发生委托 |
| 12 | 重定向型递归 Redirected Recursion | 通过重定向形成递归链 |
| 13 | 信托型委托 Trusted Delegation | 委托给可信对象 |
| 14 | 信托型重定向 Trusted Redirection | 重定向到可信目标 |
| 15 | 表亲信托型委托 Deputized Delegation | 共享父类/接口的表亲对象间委托 |
| 16 | 表亲信托型重定向 Deputized Redirection | 表亲对象间的可信重定向 |
1. 创建对象 Create Object
解释:最基础的模式——通过类构造出一个对象实例。它是所有对象关系的前提。
class User:
def __init__(self, name):
self.name = name
user = User("Alice") # 创建对象
这里 User("Alice") 触发了实例化过程。元素模式关注的是“对象被创建”这一事实,而不是具体用工厂还是构造器。
2. 检索 Retrieve
解释:访问对象中的字段或属性,把数据从对象内部读取出来。
class User:
def __init__(self, name):
self.name = name
user = User("Alice")
print(user.name) # 检索字段 name
user.name 就是一次检索。它看似简单,但它是对象封装边界上最频繁的操作之一。
3. 继承 Inheritance
解释:子类继承父类,获得父类的类型关系与可复用行为。
class Animal:
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return "Woof"
print(Dog().speak())
Dog 继承 Animal。继承不仅是代码复用,更重要的是建立了“是一种”的类型关系。
4. 抽象接口 Abstract Interface
解释:定义统一的方法契约,具体实现交给子类。Python 中可以用抽象基类或 Protocol 表达。
from abc import ABC, abstractmethod
class PaymentGateway(ABC):
@abstractmethod
def pay(self, amount):
...
class StripeGateway(PaymentGateway):
def pay(self, amount):
return f"Paid {amount} via Stripe"
PaymentGateway 规定了 pay 接口。调用方只依赖抽象接口,而不依赖具体支付实现。
5. 委托 Delegation
解释:一个对象把自己的某项职责转交给另一个对象完成。
class Engine:
def start(self):
return "Engine started"
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
return self.engine.start() # 委托给 Engine
print(Car().start())
Car.start() 并没有自己实现启动逻辑,而是调用 self.engine.start()。这就是委托:调用发生在不同对象之间,职责被转交。
6. 重定向 Redirection
解释:不同对象之间调用同一个方法签名。它与委托相近,但强调调用路径从一个对象“重定向”到另一个对象,通常接口一致。
class Logger:
def log(self, msg):
print(f"[LOG] {msg}")
class Service:
def __init__(self, logger):
self.logger = logger
def run(self):
self.logger.log("Service running") # 重定向到 Logger.log
Service(Logger()).run()
Service.run() 调用了 logger.log()。重定向关注的是方法调用路径的变化,而不是职责语义本身。
7. 集聚 Conglomeration
解释:同一个对象内部,一个方法调用该对象的其他方法,形成方法聚集。
class Order:
def process(self):
self.validate()
self.charge()
self.ship()
def validate(self):
print("Validated")
def charge(self):
print("Charged")
def ship(self):
print("Shipped")
Order().process()
process() 集聚了 validate()、charge()、ship() 三个内部方法。它描述的是对象内部的方法组织方式。
8. 递归 Recursion
解释:同一个对象的同一个方法调用自身。
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1) # 递归
递归是算法中的基础结构,在元素模式中强调“同一方法自我调用”的关系。
9. 归复方法 Revert Method
解释:方法执行后恢复到之前状态,或执行与正向操作相反的逻辑。Python 中常用上下文管理器模拟“进入—恢复”的过程。
class Transaction:
def __init__(self):
self.state = "clean"
def __enter__(self):
self.state = "dirty"
return self
def __exit__(self, *args):
self.state = "clean" # 归复:退出时恢复状态
with Transaction() as tx:
print(tx.state) # dirty
print(tx.state) # clean
归复方法常用于资源释放、状态回滚、事务恢复等场景。
10. 扩展方法 Extend Method
解释:在不修改原类定义的前提下,为对象或类“增加”方法。Python 的动态特性让这种模式非常自然。
class User:
pass
def greet(self):
return f"Hello, {self.name}"
User.greet = greet # 扩展方法
u = User()
u.name = "Bob"
print(u.greet())
这里通过给类动态绑定函数,实现了类似“扩展方法”的效果。
11. 委托型集聚 Delegated Conglomeration
解释:在同一个对象内部的方法集聚过程中,某些调用被委托给另一个对象。
class Database:
def save(self, data):
print(f"Saved: {data}")
class Service:
def __init__(self):
self.db = Database()
def create(self, data):
self.validate(data)
self.db.save(data) # 集聚中发生委托
def validate(self, data):
print("Validated")
Service().create("record")
create() 既调用了内部 validate(),又委托 db.save()。这就是“集聚 + 委托”的组合。
12. 重定向型递归 Redirected Recursion
解释:递归不是直接发生在同一个对象上,而是通过重定向到另一个同接口对象形成递归链。责任链是典型例子。
class Handler:
def __init__(self, next_handler=None):
self.next = next_handler
def handle(self, n):
if n <= 0:
return "done"
return self.next.handle(n - 1) # 重定向到下一个对象,形成递归链
h3 = Handler()
h2 = Handler(h3)
h1 = Handler(h2)
print(h1.handle(3))
调用路径是 h1 -> h2 -> h3,每一跳都是重定向,整体形成递归式调用链。
13. 信托型委托 Trusted Delegation
解释:委托发生时,调用方信任被委托对象。它强调委托关系中的可信性,例如注入一个内部认证服务。
class TrustedAuthService:
def authenticate(self, token):
return token == "valid"
class App:
def __init__(self, auth: TrustedAuthService):
self.auth = auth # 注入可信赖的委托对象
def access(self, token):
if self.auth.authenticate(token): # 信托型委托
return "Access granted"
return "Denied"
print(App(TrustedAuthService()).access("valid"))
App 把认证职责委托给一个被信任的 TrustedAuthService。
14. 信托型重定向 Trusted Redirection
解释:重定向调用时,目标方法或对象属于可信来源。它与信托型委托类似,但强调调用路径上的“重定向”关系。
class TrustedPlugin:
def execute(self):
return "plugin executed"
class Host:
def __init__(self, plugin: TrustedPlugin):
self.plugin = plugin
def run(self):
return self.plugin.execute() # 信托型重定向
print(Host(TrustedPlugin()).run())
Host.run() 把执行重定向到可信插件 TrustedPlugin.execute()。
15. 表亲信托型委托 Deputized Delegation
解释:“表亲”指两个类共享同一个父类或接口,但彼此不是直接继承关系。委托发生在这样的表亲对象之间,并带有信托性质。
class BaseWorker:
pass
class FileWorker(BaseWorker):
def work(self):
return "file processed"
class BackupWorker(BaseWorker):
def __init__(self, worker: BaseWorker):
self.worker = worker
def run(self):
return self.worker.work() # 表亲信托型委托
print(BackupWorker(FileWorker()).run())
BackupWorker 与 FileWorker 都继承 BaseWorker,是“表亲”关系;BackupWorker 把工作委托给 FileWorker。
16. 表亲信托型重定向 Deputized Redirection
解释:在表亲类之间发生重定向调用,且目标可信。它强调共享父类/接口的两个对象之间的调用路径变化。
class BaseAdapter:
pass
class JsonAdapter(BaseAdapter):
def render(self):
return "json"
class XmlAdapter(BaseAdapter):
def __init__(self, adapter: BaseAdapter):
self.adapter = adapter
def output(self):
return self.adapter.render() # 表亲信托型重定向
print(XmlAdapter(JsonAdapter()).output())
XmlAdapter 与 JsonAdapter 共享 BaseAdapter,XmlAdapter.output() 将渲染重定向到表亲对象 JsonAdapter.render()。
总结:16 种模式是一张“关系地图”
这 16 种元素模式可以分成几组理解:
- 对象与类型基础:创建对象、检索、继承、抽象接口;
- 方法调用关系:委托、重定向、集聚、递归;
- 状态与扩展:归复方法、扩展方法;
- 组合关系:委托型集聚、重定向型递归;
- 信托与表亲变体:信托型委托/重定向、表亲信托型委托/重定向。
它们真正的价值不在于“背下 16 个名字”,而在于提供一种分析语言:当你看到一个设计模式时,可以问——它由哪些基础元素组成?是委托还是重定向?是集聚还是递归?是否涉及信托或表亲关系?
用 Python 展示这些模式尤其合适,因为 Python 的动态类型和简洁语法让这些基础关系更清晰地暴露出来。理解了这 16 个“元素”,再回头看 GoF 的 23 种“化合物”,就会更容易看清它们背后的结构。

浙公网安备 33010602011771号