软件工程 - 设计模式(草稿)

设计模式

1. 发展历史

1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。

设计模式是语言无关的,它们是为了处理常见的软件设计问题而总结出来的通用方案。

但不同语言特性(如动态类型、函数式编程、元编程)可能让某些模式更自然或者不必要。

2. 创建型模式(Creational Patterns)

2.1 单例模式(Singleton)

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

核心作用:

  • 控制实例数量:严格限制类只能创建一个实例
  • 全局访问:提供统一的访问点,避免频繁创建和销毁
  • 资源共享:当多个部分需要共享同一资源时,单例模式非常有用

为了解决以下问题:

  • 资源浪费问题:某些类创建和销毁代价高昂(如数据库连接池、线程池)
  • 状态一致性问题:需要确保全局唯一状态(如配置管理器、日志系统)
  • 访问控制需求:需要集中管理对某些资源的访问(如打印机后台服务)

下面给出了4种基于Python的实现方式:Python模块即单例、重写 __new__ 方法实现、装饰器实现、元类实现

2.1.1 Python实现单例模式——模块级别天然单例

Python的模块导入机制保证了模块只有第一次被导入的时候才会执行,后面直接返回缓存,也就是对象并不会重复生成,所以使用模块导入即单例模式。

1
2
3
4
5
6
7
8
# singleton.py
class _Singleton:
    pass

instance = _Singleton()

# 使用方式
from singleton import instance

2.1.2 Python实现单例模式——重写 __new__ 方法实现

  1. 保持类本质:仍然是标准的类定义,不影响 IDE 的类型推断和代码补全
  2. 直观明确:直接在类内部实现,逻辑集中,便于维护
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Singleton:
    _instance = None
    _initialized = False
    
    def __new__(cls):
        if cls._instance is None:  # 确保单例
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not Singleton._initialized:  # 避免重复初始化
            self.load_config()  # 实际初始化代码
            self._initialized = True

# 使用
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # 输出: True

线程安全版本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from threading import Lock

class ThreadSafeSingleton:
    _instance = None
    _initialized = False
    _lock = Lock()
    
    def __new__(cls):
        if not cls._instance:  # 先判断实例是否存在,避免每次都加锁影响性能
            with cls._lock:
                if not cls._instance:  # 再次检查实例,避免多线程时在加锁前其他线程已经创建
                    cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if not Singleton._initialized:  # 避免重复初始化
            self.load_config()  # 实际初始化代码
            self._initialized = True

# 使用
import threading

def test_singleton():
    singleton = ThreadSafeSingleton()
    print(singleton)

threads = [threading.Thread(target=test_singleton) for _ in range(10)]
for t in threads:
    t.start()

对继承的影响:

子类会共享父类的单例:

由于 _instance 是类变量且通过 cls._instance 访问,子类会直接继承父类的 _instance。因此,子类的实例会和父类的实例是同一个对象(因为 cls._instance 指向的是父类的实例)。

子类无法独立成为单例:

如果子类不重写 __new__ 方法,所有子类的实例都会共享父类的单例。如果需要子类独立成为单例,必须为每个子类重写 __new__ 方法。

2.1.3 Python实现单例模式——装饰器实现

装饰器实现可以轻松应用于多个类,但是被装饰后变成了装饰器函数而不是原类型。 装饰器只对当前类有效,对其子类无效。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def singleton(cls):
    instances = {}
    
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return get_instance

@singleton
class Logger:
    pass

# 使用
logger1 = Logger()
logger2 = Logger()
print(logger1 is logger2)  # True

线程安全版本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import threading

def singleton(cls):
    instances = {}
    lock = threading.Lock()  # 全局锁

    def wrapper(*args, **kwargs):
        if cls not in instances:  # 第一次检查(无锁,提高性能)
            with lock:  # 加锁
                if cls not in instances:  # 第二次检查(防止竞态条件)
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

对继承的影响:

子类可以独立成为单例:

装饰器通过instances字典以类为键存储实例,因此父类和子类的单例是分开的(因为cls不同)。

子类默认不是单例:

如果子类不单独使用@singleton装饰,它不会自动成为单例(因为装饰器不会自动作用于子类)。

2.1.4 Python实现单例模式——元类实现

  1. 在类实例化时(call)拦截并控制实例创建,比__new__更早介入创建过程,完全掌控生命周期。
  2. 类本身保持纯净:单例逻辑完全在元类中实现,无需在类中添加任何单例相关代码。
  3. 保持完整的类继承体系,不会影响静态类型检查和代码补全。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class SingletonMeta(type):
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class Database(metaclass=SingletonMeta):
    pass
        
# 使用
db1 = Database()
db2 = Database()
print(db1 is db2)  # True

线程安全版本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class SingletonMeta(type):
    _instances = {}
    _lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            with cls._lock:
                if cls not in cls._instances:
                    cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class YourClass(metaclass=SingletonMeta):
    def __init__(self):
        """只会执行一次的初始化"""
        pass

对继承的影响:

子类自动成为单例:

元类的__call__方法会为每个类(包括子类)单独维护实例(_instances以类为键),因此子类无需额外代码即可独立成为单例。

最符合继承直觉:

这是对继承最友好的实现方式,父类和子类的单例完全独立。

2.1.5 各种单例方法对比

实现方式 线程安全 延迟初始化 代码复杂度 Pythonic程度 影响继承
模块级单例
装饰器
重写__new__
元类
线程安全版 -

2.2 工厂方法模式(Factory Method)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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()
dog = dog_factory.create_animal()
print(dog.speak())  # 输出: Woof!

2.3 抽象工厂模式(Abstract Factory)

提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from abc import ABC, abstractmethod

# 抽象产品
class Button(ABC):
    @abstractmethod
    def paint(self):
        pass

class Checkbox(ABC):
    @abstractmethod
    def paint(self):
        pass

# 具体产品
class WindowsButton(Button):
    def paint(self):
        return "Windows风格按钮"

class MacButton(Button):
    def paint(self):
        return "Mac风格按钮"

class WindowsCheckbox(Checkbox):
    def paint(self):
        return "Windows风格复选框"

class MacCheckbox(Checkbox):
    def paint(self):
        return "Mac风格复选框"

# 抽象工厂
class GUIFactory(ABC):
    @abstractmethod
    def create_button(self):
        pass
    
    @abstractmethod
    def create_checkbox(self):
        pass

# 具体工厂
class WindowsFactory(GUIFactory):
    def create_button(self):
        return WindowsButton()
    
    def create_checkbox(self):
        return WindowsCheckbox()

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())

client_code(WindowsFactory())
client_code(MacFactory())

2.4 建造者模式(Builder)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from abc import ABC, abstractmethod

# 产品类
class Pizza:
    def __init__(self):
        self.dough = ""
        self.sauce = ""
        self.topping = ""
    
    def __str__(self):
        return f"披萨: 面团[{self.dough}] 酱料[{self.sauce}] 配料[{self.topping}]"

# 抽象建造者
class PizzaBuilder(ABC):
    @abstractmethod
    def prepare_dough(self):
        pass
    
    @abstractmethod
    def add_sauce(self):
        pass
    
    @abstractmethod
    def add_topping(self):
        pass
    
    @abstractmethod
    def get_pizza(self):
        pass

# 具体建造者 - 意大利披萨
class ItalianPizzaBuilder(PizzaBuilder):
    def __init__(self):
        self.pizza = Pizza()
    
    def prepare_dough(self):
        self.pizza.dough = "薄脆面团"
    
    def add_sauce(self):
        self.pizza.sauce = "番茄酱"
    
    def add_topping(self):
        self.pizza.topping = "意大利辣香肠、蘑菇"
    
    def get_pizza(self):
        return self.pizza

# 具体建造者 - 美式披萨
class AmericanPizzaBuilder(PizzaBuilder):
    def __init__(self):
        self.pizza = Pizza()
    
    def prepare_dough(self):
        self.pizza.dough = "厚面团"
    
    def add_sauce(self):
        self.pizza.sauce = "BBQ酱"
    
    def add_topping(self):
        self.pizza.topping = "培根、玉米、洋葱"
    
    def get_pizza(self):
        return self.pizza

# 导演类
class Waiter:
    def __init__(self):
        self.builder = None
    
    def set_builder(self, builder):
        self.builder = builder
    
    def construct_pizza(self):
        self.builder.prepare_dough()
        self.builder.add_sauce()
        self.builder.add_topping()
    
    def get_pizza(self):
        return self.builder.get_pizza()

# 客户端代码
if __name__ == "__main__":
    waiter = Waiter()
    
    # 制作意大利披萨
    italian_builder = ItalianPizzaBuilder()
    waiter.set_builder(italian_builder)
    waiter.construct_pizza()
    pizza = waiter.get_pizza()
    print(pizza)  # 披萨: 面团[薄脆面团] 酱料[番茄酱] 配料[意大利辣香肠、蘑菇]
    
    # 制作美式披萨
    american_builder = AmericanPizzaBuilder()
    waiter.set_builder(american_builder)
    waiter.construct_pizza()
    pizza = waiter.get_pizza()
    print(pizza)  # 披萨: 面团[厚面团] 酱料[BBQ酱] 配料[培根、玉米、洋葱]

2.5 原型模式(Prototype)

原型模式是一种创建型设计模式,它通过复制现有对象(原型)来创建新对象,而不是通过新建类实例的方式。 这种模式特别适用于创建成本较高的对象,或者当系统需要独立于其对象的创建、组合和表示时。

原型模式的优势

  • 性能优化:克隆比新建实例更高效,特别是对于初始化成本高的对象
  • 简化对象创建:客户端不需要知道具体类名即可创建对象
  • 动态配置:可以在运行时动态添加或删除原型
  • 减少子类:避免了创建者层次结构的膨胀
  • 预设状态:新对象可以继承原型的有用状态

适用场景

  • 当系统需要独立于其对象的创建、组合和表示时
  • 当需要实例化的类是在运行时指定时(如动态加载)
  • 当创建一个类的实例比克隆一个现有实例更昂贵或更复杂时
  • 当一个系统需要配置许多原型中的一种来构建时
  • 当对象初始化需要大量资源或数据时(如数据库连接)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import copy

class Prototype:
    def __init__(self):
        self._objects = {}
    
    def register_object(self, name, obj):
        self._objects[name] = obj
    
    def unregister_object(self, name):
        del self._objects[name]
    
    def clone(self, name, **attrs):
        obj = copy.deepcopy(self._objects[name])
        obj.__dict__.update(attrs)
        return obj

class Car:
    def __init__(self):
        self.model = "Basic"
        self.color = "White"
        self.options = "Standard"
    
    def __str__(self):
        return f"{self.model} | {self.color} | {self.options}"

# 使用
prototype = Prototype()
car = Car()
prototype.register_object("basic_car", car)

car1 = prototype.clone("basic_car")
car2 = prototype.clone("basic_car", color="Red", options="Premium")
print(car1)  # 输出: Basic | White | Standard
print(car2)  # 输出: Basic | Red | Premium

3. 结构型模式(Structural Patterns)

3.1 适配器模式(Adapter)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class EuropeanSocket:
    def voltage(self):
        return 230

class AmericanSocket:
    def voltage(self):
        return 120

class EuropeanToAmericanAdapter:
    def __init__(self, socket):
        self.socket = socket
    
    def voltage(self):
        return self.socket.voltage() / 2  # 简单转换

# 使用
eu_socket = EuropeanSocket()
adapter = EuropeanToAmericanAdapter(eu_socket)
print(f"欧洲电压: {eu_socket.voltage()}V")  # 输出: 欧洲电压: 230V
print(f"适配后美国电压: {adapter.voltage()}V")  # 输出: 适配后美国电压: 115.0V

3.2 桥接模式(Bridge)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from abc import ABC, abstractmethod

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

class DrawingAPI1(DrawingAPI):
    def draw_circle(self, x, y, radius):
        print(f"API1画圆在({x}, {y})半径{radius}")

class DrawingAPI2(DrawingAPI):
    def draw_circle(self, x, y, radius):
        print(f"API2画圆在({x}, {y})半径{radius}")

# 抽象部分
class Shape:
    def __init__(self, drawing_api):
        self._drawing_api = drawing_api
    
    @abstractmethod
    def draw(self):
        pass
    
    @abstractmethod
    def resize_by_percentage(self, percent):
        pass

class CircleShape(Shape):
    def __init__(self, x, y, radius, drawing_api):
        super().__init__(drawing_api)
        self._x = x
        self._y = y
        self._radius = radius
    
    def draw(self):
        self._drawing_api.draw_circle(self._x, self._y, self._radius)
    
    def resize_by_percentage(self, percent):
        self._radius *= (1 + percent/100)

# 使用
shapes = [
    CircleShape(1, 2, 3, DrawingAPI1()),
    CircleShape(5, 7, 11, DrawingAPI2())
]

for shape in shapes:
    shape.resize_by_percentage(50)
    shape.draw()

3.3 装饰器模式(Decorator)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from abc import ABC, abstractmethod

class Coffee(ABC):
    @abstractmethod
    def cost(self):
        pass

class SimpleCoffee(Coffee):
    def cost(self):
        return 10

class CoffeeDecorator(Coffee):
    def __init__(self, coffee):
        self._coffee = coffee
    
    def cost(self):
        return self._coffee.cost()

class MilkDecorator(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 2

class SugarDecorator(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 1

# 使用
coffee = SimpleCoffee()
print(f"简单咖啡价格: {coffee.cost()}元")

milk_coffee = MilkDecorator(coffee)
print(f"加奶咖啡价格: {milk_coffee.cost()}元")

sugar_milk_coffee = SugarDecorator(milk_coffee)
print(f"加糖加奶咖啡价格: {sugar_milk_coffee.cost()}元")

3.4 组合模式(Composite)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from abc import ABC, abstractmethod

class Graphic(ABC):
    @abstractmethod
    def render(self):
        pass

class Circle(Graphic):
    def render(self):
        print("渲染圆形")

class Square(Graphic):
    def render(self):
        print("渲染方形")

class CompositeGraphic(Graphic):
    def __init__(self):
        self._graphics = []
    
    def add(self, graphic):
        self._graphics.append(graphic)
    
    def remove(self, graphic):
        self._graphics.remove(graphic)
    
    def render(self):
        for graphic in self._graphics:
            graphic.render()

# 使用
circle1 = Circle()
circle2 = Circle()
square = Square()

group = CompositeGraphic()
group.add(circle1)
group.add(circle2)
group.add(square)

group.render()

3.5 外观模式(Facade)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class CPU:
    def execute(self):
        print("CPU执行指令")

class Memory:
    def load(self):
        print("内存加载数据")

class HardDrive:
    def read(self):
        print("硬盘读取数据")

class ComputerFacade:
    def __init__(self):
        self.cpu = CPU()
        self.memory = Memory()
        self.hard_drive = HardDrive()
    
    def start(self):
        self.memory.load()
        self.hard_drive.read()
        self.cpu.execute()

# 使用
computer = ComputerFacade()
computer.start()

3.6 享元模式(Flyweight)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class TreeType:
    def __init__(self, name, color):
        self.name = name
        self.color = color
    
    def draw(self, x, y):
        print(f"在({x}, {y})绘制一棵{self.color}{self.name}")

class TreeFactory:
    _tree_types = {}
    
    @classmethod
    def get_tree_type(cls, name, color):
        key = (name, color)
        if key not in cls._tree_types:
            cls._tree_types[key] = TreeType(name, color)
        return cls._tree_types[key]

class Tree:
    def __init__(self, x, y, tree_type):
        self.x = x
        self.y = y
        self.tree_type = tree_type
    
    def draw(self):
        self.tree_type.draw(self.x, self.y)

class Forest:
    def __init__(self):
        self.trees = []
    
    def plant_tree(self, x, y, name, color):
        tree_type = TreeFactory.get_tree_type(name, color)
        tree = Tree(x, y, tree_type)
        self.trees.append(tree)
    
    def draw(self):
        for tree in self.trees:
            tree.draw()

# 使用
forest = Forest()
forest.plant_tree(1, 2, "松树", "绿色")
forest.plant_tree(3, 4, "橡树", "棕色")
forest.plant_tree(5, 6, "松树", "绿色")  # 重用松树类型
forest.draw()

3.7 代理模式(Proxy)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from abc import ABC, abstractmethod

class Subject(ABC):
    @abstractmethod
    def request(self):
        pass

class RealSubject(Subject):
    def request(self):
        print("真实主题处理请求")

class Proxy(Subject):
    def __init__(self, real_subject):
        self._real_subject = real_subject
    
    def request(self):
        if self.check_access():
            self._real_subject.request()
            self.log_access()
    
    def check_access(self):
        print("代理: 检查访问权限")
        return True
    
    def log_access(self):
        print("代理: 记录访问时间")

# 使用
real_subject = RealSubject()
proxy = Proxy(real_subject)
proxy.request()

4. 行为型模式(Behavioral Patterns)

4.1 观察者模式(Observer)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from abc import ABC, abstractmethod

class Observer(ABC):
    @abstractmethod
    def update(self, subject):
        pass

class Subject:
    def __init__(self):
        self._observers = []
        self._state = 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)
    
    @property
    def state(self):
        return self._state
    
    @state.setter
    def state(self, state):
        self._state = state
        self.notify()

class ConcreteObserverA(Observer):
    def update(self, subject):
        if subject.state < 3:
            print("观察者A: 状态小于3")

class ConcreteObserverB(Observer):
    def update(self, subject):
        if subject.state >= 2:
            print("观察者B: 状态大于等于2")

# 使用
subject = Subject()

observer_a = ConcreteObserverA()
subject.attach(observer_a)

observer_b = ConcreteObserverB()
subject.attach(observer_b)

subject.state = 1
subject.state = 2
subject.state = 3

4.2 策略模式(Strategy)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

class CreditCardPayment(PaymentStrategy):
    def __init__(self, card_number, expiry_date, cvv):
        self.card_number = card_number
        self.expiry_date = expiry_date
        self.cvv = cvv
    
    def pay(self, amount):
        print(f"使用信用卡支付 {amount} 元 (卡号: {self.card_number[-4:]})")

class AlipayPayment(PaymentStrategy):
    def __init__(self, alipay_id):
        self.alipay_id = alipay_id
    
    def pay(self, amount):
        print(f"使用支付宝支付 {amount} 元 (账号: {self.alipay_id})")

class PaymentContext:
    def __init__(self, strategy):
        self._strategy = strategy
    
    def execute_payment(self, amount):
        self._strategy.pay(amount)

# 使用
credit_card = CreditCardPayment("1234567890123456", "12/25", "123")
alipay = AlipayPayment("user@example.com")

payment = PaymentContext(credit_card)
payment.execute_payment(100)

payment = PaymentContext(alipay)
payment.execute_payment(200)

4.3 模板方法模式(Template Method)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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 Cricket(Game):
    def initialize(self):
        print("板球游戏初始化! 准备投球。")
    
    def start_play(self):
        print("板球游戏开始! 享受游戏。")
    
    def end_play(self):
        print("板球游戏结束!")

class Football(Game):
    def initialize(self):
        print("足球游戏初始化! 准备开球。")
    
    def start_play(self):
        print("足球游戏开始! 享受游戏。")
    
    def end_play(self):
        print("足球游戏结束!")

# 使用
game = Cricket()
game.play()

print()

game = Football()
game.play()

4.4 命令模式(Command)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from abc import ABC, abstractmethod

class Command(ABC):
    @abstractmethod
    def execute(self):
        pass

class Light:
    def on(self):
        print("灯亮了")
    
    def off(self):
        print("灯灭了")

class LightOnCommand(Command):
    def __init__(self, light):
        self._light = light
    
    def execute(self):
        self._light.on()

class LightOffCommand(Command):
    def __init__(self, light):
        self._light = light
    
    def execute(self):
        self._light.off()

class RemoteControl:
    def __init__(self):
        self._commands = {}
    
    def register(self, command_name, command):
        self._commands[command_name] = command
    
    def execute(self, command_name):
        if command_name in self._commands:
            self._commands[command_name].execute()
        else:
            print(f"命令 '{command_name}' 未找到")

# 使用
light = Light()
light_on = LightOnCommand(light)
light_off = LightOffCommand(light)

remote = RemoteControl()
remote.register("on", light_on)
remote.register("off", light_off)

remote.execute("on")   # 灯亮了
remote.execute("off")  # 灯灭了

4.5 责任链模式(Chain of Responsibility)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from abc import ABC, abstractmethod

class Handler(ABC):
    def __init__(self, successor=None):
        self._successor = successor
    
    @abstractmethod
    def handle_request(self, request):
        pass

class ConcreteHandler1(Handler):
    def handle_request(self, request):
        if request == "A":
            print("处理器1处理请求A")
        elif self._successor is not None:
            self._successor.handle_request(request)

class ConcreteHandler2(Handler):
    def handle_request(self, request):
        if request == "B":
            print("处理器2处理请求B")
        elif self._successor is not None:
            self._successor.handle_request(request)

class DefaultHandler(Handler):
    def handle_request(self, request):
        print(f"默认处理器: 没有处理器能处理请求'{request}'")

# 使用
handler_chain = ConcreteHandler1(ConcreteHandler2(DefaultHandler()))

handler_chain.handle_request("A")  # 处理器1处理请求A
handler_chain.handle_request("B")  # 处理器2处理请求B
handler_chain.handle_request("C")  # 默认处理器: 没有处理器能处理请求'C'

4.6 状态模式(State)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from abc import ABC, abstractmethod

class State(ABC):
    @abstractmethod
    def handle(self):
        pass

class ConcreteStateA(State):
    def handle(self):
        print("处理状态A的行为")
        return ConcreteStateB()

class ConcreteStateB(State):
    def handle(self):
        print("处理状态B的行为")
        return ConcreteStateA()

class Context:
    def __init__(self, state):
        self._state = state
    
    def request(self):
        self._state = self._state.handle()

# 使用
context = Context(ConcreteStateA())

context.request()  # 处理状态A的行为
context.request()  # 处理状态B的行为
context.request()  # 处理状态A的行为

4.7 访问者模式(Visitor)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from abc import ABC, abstractmethod

class Element(ABC):
    @abstractmethod
    def accept(self, visitor):
        pass

class ConcreteElementA(Element):
    def accept(self, visitor):
        visitor.visit_element_a(self)
    
    def operation_a(self):
        return "元素A的操作"

class ConcreteElementB(Element):
    def accept(self, visitor):
        visitor.visit_element_b(self)
    
    def operation_b(self):
        return "元素B的操作"

class Visitor(ABC):
    @abstractmethod
    def visit_element_a(self, element):
        pass
    
    @abstractmethod
    def visit_element_b(self, element):
        pass

class ConcreteVisitor1(Visitor):
    def visit_element_a(self, element):
        print(f"访问者1: {element.operation_a()}")
    
    def visit_element_b(self, element):
        print(f"访问者1: {element.operation_b()}")

class ConcreteVisitor2(Visitor):
    def visit_element_a(self, element):
        print(f"访问者2: {element.operation_a()}")
    
    def visit_element_b(self, element):
        print(f"访问者2: {element.operation_b()}")

# 使用
elements = [ConcreteElementA(), ConcreteElementB()]

visitor1 = ConcreteVisitor1()
for element in elements:
    element.accept(visitor1)

print()

visitor2 = ConcreteVisitor2()
for element in elements:
    element.accept(visitor2)

4.8 中介者模式(Mediator)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from abc import ABC, abstractmethod

class Mediator(ABC):
    @abstractmethod
    def notify(self, sender, event):
        pass

class Component:
    def __init__(self, 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):
        print("按钮被点击")
        self.mediator.notify(self, "click")

class TextBox(Component):
    def update_text(self, text):
        print(f"文本框更新为: {text}")
        self.mediator.notify(self, "text_update")

class DialogMediator(Mediator):
    def __init__(self, button, textbox):
        self._button = button
        self._button.mediator = self
        self._textbox = textbox
        self._textbox.mediator = self
    
    def notify(self, sender, event):
        if sender == self._button and event == "click":
            print("中介者: 按钮点击事件处理")
            self._textbox.update_text("新文本")
        elif sender == self._textbox and event == "text_update":
            print("中介者: 文本框更新事件处理")

# 使用
button = Button()
textbox = TextBox()
mediator = DialogMediator(button, textbox)

button.click()

4.9 备忘录模式(Memento)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class EditorMemento:
    def __init__(self, content):
        self._content = content
    
    @property
    def content(self):
        return self._content

class Editor:
    def __init__(self):
        self._content = ""
    
    def type(self, text):
        self._content += text
    
    def save(self):
        return EditorMemento(self._content)
    
    def restore(self, memento):
        self._content = memento.content
    
    def __str__(self):
        return self._content

# 使用
editor = Editor()

# 编辑内容
editor.type("第一行文字\n")
editor.type("第二行文字\n")

# 保存状态
saved = editor.save()

# 继续编辑
editor.type("第三行文字\n")
print("当前内容:")
print(editor)

# 恢复到之前保存的状态
editor.restore(saved)
print("\n恢复后的内容:")
print(editor)

4.10 解释器模式(Interpreter)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from abc import ABC, abstractmethod

class Context:
    def __init__(self):
        self.variables = {}

class Expression(ABC):
    @abstractmethod
    def interpret(self, context):
        pass

class Variable(Expression):
    def __init__(self, name):
        self.name = name
    
    def interpret(self, context):
        return context.variables.get(self.name, 0)

class Number(Expression):
    def __init__(self, number):
        self.number = number
    
    def interpret(self, context):
        return self.number

class Add(Expression):
    def __init__(self, left, right):
        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, right):
        self.left = left
        self.right = right
    
    def interpret(self, context):
        return self.left.interpret(context) - self.right.interpret(context)

# 使用
context = Context()
context.variables['x'] = 10
context.variables['y'] = 5

# 构建表达式: x + y - 3
expression = Subtract(
    Add(Variable('x'), Variable('y')),
    Number(3)
)

result = expression.interpret(context)
print(f"结果: {result}")  # 输出: 结果: 12

4.11 迭代器模式(Iterator)

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from collections.abc import Iterator

class Book:
    def __init__(self, title):
        self.title = title
    
    def __str__(self):
        return self.title

class BookShelf:
    def __init__(self):
        self._books = []
    
    def add_book(self, book):
        self._books.append(book)
    
    def __iter__(self):
        return BookShelfIterator(self)

class BookShelfIterator(Iterator):
    def __init__(self, book_shelf):
        self._book_shelf = book_shelf
        self._index = 0
    
    def __next__(self):
        if self._index < len(self._book_shelf._books):
            book = self._book_shelf._books[self._index]
            self._index += 1
            return book
        raise StopIteration()

# 使用
shelf = BookShelf()
shelf.add_book(Book("设计模式"))
shelf.add_book(Book("Python编程"))
shelf.add_book(Book("算法导论"))

for book in shelf:
    print(book)

网友总结表格:

设计模式 简述 一句话归纳 目的 生活案例
工厂模式(Factory Pattern) 不同条件下创建不同实例 产品标准化,生产更高效 封装创建细节 实体工厂
抽象工厂(Factory Pattern) 提供一个创建一组相关或相互依赖对象的接口 产品标准化,生产更高效 封装创建细节 实体工厂
单例模式(Singleton Pattern) 保证一个类仅有一个实例,并且提供一个全局访问点 世上只有一个我 保证独一无二 CEO
原型模式(Prototype Pattern) 通过拷贝原型创建新的对象 拔一根猴毛,吹出千万个 高效创建对象 克隆
建造者模式(Builder Pattern) 用来创建复杂的复合对象 高配中配和低配,想选哪配就哪配 开放个性配置步骤 选配
代理模式(Proxy Pattern) 为其他对象提供一种代理以控制对这个对象的访问 没有资源没时间,得找别人来帮忙 增强职责 媒婆
外观模式(Facade Pattern) 对外提供一个统一的接口用来访问子系统 打开一扇门,通向全世界 统一访问入口 slf4j
装饰器模式(Decorator Pattern) 为对象添加新功能 他大舅他二舅都是他舅 灵活扩展、同宗同源 JAVA IO ,奶茶
享元模式(Flyweight Pattern) 使用对象池来减少重复对象的创建 优化资源配置,减少重复浪费 共享资源池 数据库连接池
组合模式(Composite Pattern) 将整体与局部(树形结构)进行递归组合,让客户端能够以一种的方式对其进行处理 人在一起叫团伙,心在一起叫团队 统一整体和个体 组织架构树
适配器模式(Adapter Pattern) 将原来不兼容的两个类融合在一起 万能充电器 兼容转换 电源适配
桥接模式(Bridge Pattern) 将两个能够独立变化的部分分离开来 约定优于配置 不允许用继承
模板模式(Template Pattern) 定义一套流程模板,根据需要实现模板中的操作 流程全部标准化,需要微调请覆盖 逻辑复用 把大象装进冰箱
策略模式(Strategy Pattern) 封装不同的算法,算法之间能互相替换 条条大道通罗马,具体哪条你来定 把选择权交给用户 选择支付方式
责任链模式(Chain of Responsibility Pattern) 拦截的类都实现统一接口,每个接收者都包含对下一个接收者的引用。将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。 各人自扫门前雪,莫管他们上霜 解耦处理逻辑 踢皮球
迭代器模式(Iterator Pattern 提供一种方法顺序访问一个聚合对象中的各个元素 流水线上坐一天,每个包裹扫一遍 统一对集合的访问方式 逐个检票进站
命令模式(Command Pattern) 将请求封装成命令,并记录下来,能够撤销与重做 运筹帷幄之中,决胜千里之外 解耦请求和处理 遥控器
状态模式(State Pattern) 根据不同的状态做出不同的行为 状态驱动行为,行为决定状态 绑定状态和行为 订单状态跟踪
备忘录模式(Memento Pattern) 保存对象的状态,在需要时进行恢复 失足不成千古恨,想重来时就重来 备份、后悔机制 草稿箱
中介者模式(Mediator Pattern) 将对象之间的通信关联关系封装到一个中介类中单独处理,从而使其耦合松散 联系方式我给你,怎么搞定我不管 统一管理网状资源 朋友圈
解释器模式(Interpreter Pattern) 给定一个语言,定义它的语法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子 我想说”方言“,一切解释权都归我 实现特定语法解析 摩斯密码
观察者模式(Observer Pattern) 状态发生改变时通知观察者,一对多的关系 到点就通知我 解耦观察者与被观察者 闹钟
访问者模式(Visitor Pattern) 稳定数据结构,定义新的操作行为 横看成岭侧成峰,远近高低各不同 解耦数据结构和数据操作 KPI考核
updatedupdated2026-02-052026-02-05