为什么要有设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class DatabaseConnection: def __init__(self, host, port, username, password): self.host = host self.port = port self.username = username self.password = password
def connect(self): return f"Connecting to database at {self.host}:{self.port} with username '{self.username}'"
def client(): main_db = DatabaseConnection('localhost', 3306, 'root', 'password123') analytics_db = DatabaseConnection('192.168.1.1', 5432, 'admin', 'securepass') cache_db = DatabaseConnection('10.0.0.1', 27017, 'cacheuser', 'cachepass')
print(main_db.connect()) print(analytics_db.connect()) print(cache_db.connect())
client()
|
这是数据库连接类的范例,其存在以下问题
- 数据库连接信息(主机、端口、用户名、密码)直接写在代码中,缺乏配置管理,难以在不同环境间切换,如果要更改数据库的信息,就要更改项目中每一处的连接数据库的参数,难以维护
- 每次都需要手动传入相同类型的参数,增加出错的风险
工厂模式(Factory Pattern)
工厂模式
是一种创建型设计模式,它提供了一种创建对象的接口,但让子类决定实例化哪一个类。换句话说:把对象的创建过程封装起来,调用者不需要关心具体创建的是哪个类,只需要知道“我要一个某种类型的东西”。
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
| def connection_factory(db_type): db_configs = { 'main': { 'host': 'localhost', 'port': 3306, 'username': 'root', 'password': 'password123' }, 'analytics': { 'host': '192.168.1.1', 'port': 5432, 'username': 'admin', 'password': 'securepass' }, 'cache': { 'host': '10.0.0.1', 'port': 27017, 'username': 'cacheuser', 'password': 'cachepass' } } return DatabaseConnection(**db_configs[db_type])
# 测试工厂模式 if __name__ == "__main__": # 使用工厂函数创建不同类型的数据库连接 main_db = connection_factory('main') analytics_db = connection_factory('analytics') cache_db = connection_factory('cache') # 测试连接 print(main_db.connect()) print(analytics_db.connect()) print(cache_db.connect())
|
将数据库的配置信息提取到config.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #factory_pattern.py def connection_factory(db_type): """ 工厂函数:根据数据库类型创建相应的数据库连接 Args: db_type (str): 数据库类型 ('main', 'analytics', 'cache') Returns: DatabaseConnection: 数据库连接实例 Raises: KeyError: 当提供的数据库类型不存在时 """ from config import DATABASE_CONFIGS if db_type not in DATABASE_CONFIGS: raise ValueError(f"Unknown database type: {db_type}. Available types: {list(DATABASE_CONFIGS.keys())}") return DatabaseConnection(**DATABASE_CONFIGS[db_type])
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #config.py # 数据库配置字典 DATABASE_CONFIGS = { 'main': { 'host': 'localhost', 'port': 3306, 'username': 'root', 'password': 'password123' }, 'analytics': { 'host': '192.168.1.1', 'port': 5432, 'username': 'admin', 'password': 'securepass' }, 'cache': { 'host': '10.0.0.1', 'port': 27017, 'username': 'cacheuser', 'password': 'cachepass' } }
|
为什么要这么做
- 所有配置信息都在一个地方,便于统一管理和维护
- 易于修改 :配置变更不需要修改业务逻辑代码
工厂模式的核心就是工厂函数
工厂函数是一个返回对象的函数(而不是类),它封装了对象的创建逻辑,根据输入参数决定返回哪种具体对象。
建造者模式(Builder Pattern)
当你需要创建一个有很多属性、配置步骤繁多的对象时(比如一辆汽车、一个
HTTP 请求、一个数据库连接配置),直接用构造函数会非常混乱。
建造者模式通过“分步构建 +
最终组装”的方式,让创建过程清晰、灵活、可读性强。
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
| class DatabaseConnectionBuilder: """数据库连接建造者类""" def __init__(self,host,port,username,password): self._config = { 'host': host, 'port': port, 'username': username, 'password': password, } def set_max_connections(self, max_connections): """设置最大连接数""" if max_connections is not None and max_connections <= 0: raise ValueError("Max connections must be positive") self._config['max_connections'] = max_connections return self def set_timeout(self, timeout): """设置超时时间""" if timeout is not None and timeout <= 0: raise ValueError("Connect timeout must be positive") self._config['timeout'] = timeout return self def build(self): """构建最终的数据库连接对象""" return DatabaseConnection(**self._config) # 演示建造者模式的使用 if __name__ == "__main__": # 创建一个数据库连接建造者 builder = DatabaseConnectionBuilder( host='localhost', port=3306, username='root', password='password123' ) # 使用建造者模式构建数据库连接 connection = builder.set_max_connections(100) \ .set_timeout(30) \ .enable_ssl() \ .set_connection_pool('my_pool') \ .set_retry_attempts(3) \ .enable_compression() \ .set_read_preference('secondaryPreferred') \ .build()
|
单例模式(Singleton Pattern)
单例模式确保一个类只有一个实例,并提供一个全局访问点来获取该实例。
换句话说:
无论你调用多少次“创建对象”,返回的始终是同一个对象。
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
| class DatabaseConnection: """数据库连接单例类""" _instance = None _lock = threading.Lock() # 线程锁,确保线程安全 def __new__(cls, *args, **kwargs): """重写__new__方法实现单例模式""" if cls._instance is None: with cls._lock: # 使用双重检查锁定 if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self, host, port, username, password): """初始化数据库连接参数""" # 防止重复初始化 if hasattr(self, '_initialized'): return self.host = host self.port = port self.username = username self.password = password self._initialized = True def connect(self): """连接数据库""" return f"Connecting to database at {self.host}:{self.port} with username '{self.username}'"
def client(): db1 = DatabaseConnection(host='localhost', port=3306, username='root', password='password') db2 = DatabaseConnection(host='localhost', port=3306, username='root', password='password') print(db1 is db2)
client()
|
参考资料
【设计模式
inPy】一个视频搞懂三种设计模式:工厂、建造者和单例_哔哩哔哩_bilibili
为什么你应该忘掉设计模式?_哔哩哔哩_bilibili
【设计模式inPython】策略模式:不要再用一个类装所有方法啦!_哔哩哔哩_bilibili