从“化合物”到“元素”:用 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 种元素模式可以分成几组理解:

  1. 对象与类型基础:创建对象、检索、继承、抽象接口;
  2. 方法调用关系:委托、重定向、集聚、递归;
  3. 状态与扩展:归复方法、扩展方法;
  4. 组合关系:委托型集聚、重定向型递归;
  5. 信托与表亲变体:信托型委托/重定向、表亲信托型委托/重定向。

它们真正的价值不在于“背下 16 个名字”,而在于提供一种分析语言:当你看到一个设计模式时,可以问——它由哪些基础元素组成?是委托还是重定向?是集聚还是递归?是否涉及信托或表亲关系?

用 Python 展示这些模式尤其合适,因为 Python 的动态类型和简洁语法让这些基础关系更清晰地暴露出来。理解了这 16 个“元素”,再回头看 GoF 的 23 种“化合物”,就会更容易看清它们背后的结构。

posted @ 2026-10-20 10:32  绝不原创的飞龙  阅读(13)  评论(0)    收藏  举报