1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。
设计模式是语言无关的,它们是为了处理常见的软件设计问题而总结出来的通用方案。
但不同语言特性(如动态类型、函数式编程、元编程)可能让某些模式更自然或者不必要。
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
核心作用:
- 控制实例数量:严格限制类只能创建一个实例
- 全局访问:提供统一的访问点,避免频繁创建和销毁
- 资源共享:当多个部分需要共享同一资源时,单例模式非常有用
为了解决以下问题:
- 资源浪费问题:某些类创建和销毁代价高昂(如数据库连接池、线程池)
- 状态一致性问题:需要确保全局唯一状态(如配置管理器、日志系统)
- 访问控制需求:需要集中管理对某些资源的访问(如打印机后台服务)
下面给出了4种基于Python的实现方式:Python模块即单例、重写 __new__ 方法实现、装饰器实现、元类实现。
Python的模块导入机制保证了模块只有第一次被导入的时候才会执行,后面直接返回缓存,也就是对象并不会重复生成,所以使用模块导入即单例模式。
1
2
3
4
5
6
7
8
|
# singleton.py
class _Singleton:
pass
instance = _Singleton()
# 使用方式
from singleton import instance
|
- 保持类本质:仍然是标准的类定义,不影响 IDE 的类型推断和代码补全
- 直观明确:直接在类内部实现,逻辑集中,便于维护
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__ 方法。
装饰器实现可以轻松应用于多个类,但是被装饰后变成了装饰器函数而不是原类型。
装饰器只对当前类有效,对其子类无效。
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装饰,它不会自动成为单例(因为装饰器不会自动作用于子类)。
- 在类实例化时(call)拦截并控制实例创建,比__new__更早介入创建过程,完全掌控生命周期。
- 类本身保持纯净:单例逻辑完全在元类中实现,无需在类中添加任何单例相关代码。
- 保持完整的类继承体系,不会影响静态类型检查和代码补全。
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以类为键),因此子类无需额外代码即可独立成为单例。
最符合继承直觉:
这是对继承最友好的实现方式,父类和子类的单例完全独立。
| 实现方式 |
线程安全 |
延迟初始化 |
代码复杂度 |
Pythonic程度 |
影响继承 |
| 模块级单例 |
是 |
否 |
低 |
高 |
否 |
| 装饰器 |
否 |
是 |
中 |
中 |
否 |
| 重写__new__ |
否 |
是 |
低 |
中 |
否 |
| 元类 |
否 |
是 |
高 |
高 |
是 |
| 线程安全版 |
是 |
是 |
高 |
中 |
- |
定义一个创建对象的接口,但让子类决定实例化哪个类。
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!
|
提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。
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())
|
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
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酱] 配料[培根、玉米、洋葱]
|
原型模式是一种创建型设计模式,它通过复制现有对象(原型)来创建新对象,而不是通过新建类实例的方式。
这种模式特别适用于创建成本较高的对象,或者当系统需要独立于其对象的创建、组合和表示时。
原型模式的优势
- 性能优化:克隆比新建实例更高效,特别是对于初始化成本高的对象
- 简化对象创建:客户端不需要知道具体类名即可创建对象
- 动态配置:可以在运行时动态添加或删除原型
- 减少子类:避免了创建者层次结构的膨胀
- 预设状态:新对象可以继承原型的有用状态
适用场景
- 当系统需要独立于其对象的创建、组合和表示时
- 当需要实例化的类是在运行时指定时(如动态加载)
- 当创建一个类的实例比克隆一个现有实例更昂贵或更复杂时
- 当一个系统需要配置许多原型中的一种来构建时
- 当对象初始化需要大量资源或数据时(如数据库连接)
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
|
将一个类的接口转换成客户希望的另一个接口。
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
|
将抽象部分与实现部分分离,使它们可以独立变化。
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()
|
动态地给一个对象添加一些额外的职责。
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()}元")
|
将对象组合成树形结构以表示"部分-整体"的层次结构。
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()
|
为子系统中的一组接口提供一个一致的界面。
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()
|
运用共享技术有效地支持大量细粒度的对象。
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()
|
为其他对象提供一种代理以控制对这个对象的访问。
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()
|
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
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
|
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
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)
|
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
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()
|
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
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") # 灯灭了
|
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
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'
|
允许一个对象在其内部状态改变时改变它的行为。
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的行为
|
表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
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)
|
用一个中介对象来封装一系列的对象交互。
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()
|
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
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)
|
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
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
|
提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
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考核 |