创建型设计模式(Creational Design Patterns) 是一类用于创建对象的设计模式,旨在解决对象创建时的复杂性,并确保创建过程满足设计需求。这些模式通过封装实例化过程,使得代码在创建对象时更加灵活、可扩展,并降低了与对象创建相关的耦合性。
创建型设计模式的特点
- 解耦创建过程:将对象创建的具体细节隐藏起来,使得系统能够在不影响其使用的情况下轻松改变对象的创建方式。
- 复用性:能够避免重复创建对象,节省资源。
- 灵活性:通过模式的使用,可以灵活应对不同的创建场景,保证系统的扩展性。
创建型设计模式常见的几种模式包括单例模式(Singleton Pattern) 、工厂模式(Factory Pattern) 、原型模式(Prototype Pattern) 、建造者模式(Builder Pattern) ,以及Monostate 模式。
三个常见的创建型设计模式:
1. 单例模式(Singleton Pattern)
原理
单例模式确保一个类只有一个实例,并提供一个全局访问点。它通常用于共享资源(如数据库连接、配置管理等),避免在系统中创建多余的对象。
示例
我们通过元类和装饰器实现了单例模式,这些方法都确保无论实例化多少次,程序中始终只存在一个实例。
python
# 使用元类实现单例模式
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
def __init__(self):
self.value = 42
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True,表明s1和s2是同一实例
使用场景
- 全局配置:系统中只需要一个配置对象,避免重复配置和不一致。
- 日志记录器:全局共享一个日志对象,避免多个日志文件或记录器的混乱。
好处
- 控制实例数量:确保系统只创建一个对象,避免资源浪费。
- 全局访问点:系统中可以轻松地访问单例对象,简化代码结构。
2. 通过 import
实现单例
原理
在 Python 中,模块在首次 import
时被加载到内存中,之后的 import
只是返回之前加载的对象。因此,利用模块的这一特性,能够实现全局共享的单例模式。
示例
python
# config.py
class Config:
def __init__(self):
self.value = 42
config = Config()
# main.py
from config import config
print(config.value) # 42
config.value = 100
# other.py
from config import config
print(config.value) # 100,表明在不同模块中共享同一实例
使用场景
- 全局状态管理 :当程序中的某个状态或配置需要在多个模块间共享时,使用
import
实现单例能够保证一致性。 - 资源管理:通过模块实现的单例模式,确保系统中的资源(如文件句柄、数据库连接等)不会被多次创建。
好处
- 简单易用 :
import
本身就是一种单例模式的实现,不需要额外的代码逻辑来确保对象的唯一性。 - 全局访问 :通过
import
,在任何地方都可以访问同一个对象实例。
3. Monostate 模式(共享状态)
原理
Monostate 模式与单例模式类似,但不同之处在于 Monostate 模式允许创建多个实例,这些实例共享相同的状态。状态保存在类属性中,而不是实例属性中。
示例
我们之前展示了如何通过类属性共享状态,以及如何使用 @property
和 @<variable>.setter
装饰器来控制属性的访问和修改。
python
class Monostate:
_shared_state = {"_value": 42}
def __init__(self):
self.__dict__ = self._shared_state
@property
def value(self):
return self._shared_state["_value"]
@value.setter
def value(self, new_value):
if new_value < 0:
raise ValueError("Value cannot be negative")
self._shared_state["_value"] = new_value
# 测试 Monostate 模式
instance1 = Monostate()
instance2 = Monostate()
instance1.value = 100
print(instance2.value) # 输出 100,表明两个实例共享相同的状态
使用场景
- 对象间共享状态:当需要多个对象共享某些全局状态或配置,但仍希望这些对象可以被单独实例化时,可以使用 Monostate 模式。
- 分布式系统:在需要多个实例共享状态的场景中,如集群中的状态同步。
好处
- 灵活性:Monostate 模式允许创建多个对象,但保持共享的状态,使其比传统的单例模式更加灵活。
- 状态一致性:通过共享类属性,确保所有实例在状态上保持一致。
使用 @property
和 @<variable>.setter
的好处
- 封装访问控制 :通过
@property
和@setter
,可以对共享的状态进行更加严格的控制和验证。 - 更好的代码可维护性:这些装饰器使得状态的访问和修改更加直观,提高了代码的可读性。
总结
-
单例模式(Singleton Pattern):保证系统中只有一个实例,适合用于全局状态、资源共享的场景。可以通过元类或装饰器实现单例。
-
通过
import
实现单例:利用 Python 模块的天然单例特性,简化全局对象的管理,适用于全局配置、资源共享等场景。 -
Monostate 模式(共享状态):允许多个实例共享状态,而不是共享同一个对象。通过类属性的方式,多个对象可以在状态上保持一致性,适用于多个实例需要共享状态的场景。
这些创建型模式有效地解决了对象创建的复杂性问题,使代码在面临复杂对象创建需求时更具灵活性和扩展性。