单例模式
懒汉式
class SingleTon:
# 类属性
_obj = None # 用来存储对象
# 创造对象
def __new__(cls, *args, **kwargs):
# 如果对象不存在,就创造一个对象
if cls._obj is None:
cls._obj = super().__new__(cls, *args, *kwargs)
# 返回对象
return cls._obj
if __name__ == '__main__':
obj_1 = SingleTon() # 创造一个对象
obj_2 = SingleTon() # 再次创造一个对象
print("obj_1的内存地址:", id(obj_1)) # obj_1的内存地址: 2801491317584
print("obj_2的内存地址:", id(obj_2)) # obj_2的内存地址: 2801491317584
print(obj_1 is obj_2) # True
饿汉式
- test.py
class SingleTon:
pass
# 创建一个对象
obj = SingleTon
# 提供接口
def get_instance():
return obj
- main.py
from test import get_instance
if __name__ == '__main__':
obj_1 = get_instance() # 创建一个对象
obj_2 = get_instance() # 再创建一个对象
print(obj_1 is obj_2) # True
工厂模式
简单工厂模式
"""
实现:简单计算器(加减乘除)
1. 提供一个抽象产品类
2. 提供多个具体产品类
3. 提供一个工厂类
"""
from abc import ABC, abstractmethod
# 计算器(抽象产品类)
class Calculator(ABC): # 继承 ABC 抽象类
def __init__(self):
self.left_value = 0
self.right_value = 0
def set(self, left_value, right_value):
self.left_value = left_value
self.right_value = right_value
return self
@abstractmethod
def run(self): # 抽象方法
pass
# 加法计算器(具体产品类)
class AddCalculator(Calculator): # 继承 Calculator 类
def run(self):
return self.left_value + self.right_value
# 减法计算器(具体产品类)
class SubCalculator(Calculator): # 继承 Calculator 类
def run(self):
return self.left_value - self.right_value
# 乘法计算器(具体产品类)
class MulCalculator(Calculator): # 继承 Calculator 类
def run(self):
return self.left_value * self.right_value
# 除法计算器(具体产品类)
class DivCalculator(Calculator): # 继承 Calculator 类
def run(self):
if self.right_value == 0:
raise "除数不能为零!"
return self.left_value / self.right_value
# 工厂类
class Factory:
@staticmethod
def produce_calculator(char): # 类方法
match char:
case "+":
return AddCalculator() # 创建对象
case "-":
return SubCalculator() # 创建对象
case "*":
return MulCalculator() # 创建对象
case "/":
return DivCalculator() # 创建对象
case _:
raise "不支持其他的运算符!"
if __name__ == '__main__':
# 工厂生产4种类型的计算器产品
add_calculator = Factory.produce_calculator("+") # 加法计算器
sub_calculator = Factory.produce_calculator("-") # 减法计算器
mul_calculator = Factory.produce_calculator("*") # 乘法计算器
div_calculator = Factory.produce_calculator("/") # 除法计算器
# 使用除法计算器
res = div_calculator.set(10, 5).run() # 设置左值(被除数)和右值(除数),然后运行
print(res) # 2.0
工厂方法模式
from abc import ABC, abstractmethod
# 产品(抽象产品类)
class Product(ABC): # 继承 ABC 抽象类
# 抽象:此产品补充燃料的功能
@abstractmethod
def fuel(self):
pass
# 抽象:此产品起飞的功能
@abstractmethod
def fly(self):
pass
# 飞机(具体产品类)
class PlaneProduct(Product): # 继承 Product 产品类
# 实现:此产品补充燃料的功能
def fuel(self):
print(f"飞机-CS{id(self)},补充燃料中...")
# 实现:此产品起飞的功能
def fly(self):
print(f"飞机-CS{id(self)},起飞!")
# 火箭(具体产品类)
class RocketProduct(Product): # 继承 Product 产品类
# 实现:此产品补充燃料的功能
def fuel(self):
print(f"火箭-CS{id(self)},补充燃料中...")
# 实现:此产品起飞的功能
def fly(self):
print(f"火箭-CS{id(self)},起飞!")
# 工厂(抽象工厂类)
class Factory(ABC):
# 抽象:生产产品
@abstractmethod
def produce_product(self):
pass
# 飞机工厂(具体工厂类)
class PlaneFactory(Factory):
# 具体:生产飞机产品
def produce_product(self):
return PlaneProduct() # 创建对象,并返回出去
# 火箭工厂(具体工厂类)
class RocketFactory(Factory):
# 具体:生产火箭产品
def produce_product(self):
return RocketProduct() # 创建对象,并返回出去
# 演示
def work(factory):
product = factory.produce_product() # 工厂生产产品
product.fuel() # 使用产品的"补充燃料"功能
product.fly() # 使用产品"飞行"的功能
if __name__ == '__main__':
# 创建一个飞机工厂
plane_factory = PlaneFactory()
# 让飞机工厂干活
work(plane_factory)
# 创建一个火箭工厂
rocket_factory = RocketFactory()
# 让火箭工厂干活
work(rocket_factory)
抽象工厂模式
from abc import ABC, abstractmethod
# 抽象产品
class Product(ABC):
@abstractmethod
def show(self):
pass
# 抽象键盘产品
class KeyBoard(Product):
@abstractmethod
def show(self):
pass
# 抽象鼠标产品
class Mouse(Product):
@abstractmethod
def show(self):
pass
# 具体键盘产品1
class MikaKeyBoard(KeyBoard):
def show(self):
print("Mika键盘")
# 具体键盘产品2
class PikiKeyBoard(KeyBoard):
def show(self):
print("Piki键盘")
# 具体鼠标产品1
class MikaMouse(Mouse):
def show(self):
print("Mika鼠标")
# 具体鼠标产品2
class PikiMouse(Mouse):
def show(self):
print("Piki鼠标")
# 抽象工厂类
class Factory(ABC):
@abstractmethod
def produce_keyboard(self):
pass
@abstractmethod
def produce_mouse(self):
pass
# 具体工厂1
class MikaFactory(Factory):
def produce_keyboard(self):
return MikaKeyBoard()
def produce_mouse(self):
return MikaMouse()
# 具体工厂2
class PikiFactory(Factory):
def produce_keyboard(self):
return PikiKeyBoard()
def produce_mouse(self):
return PikiMouse()
# 测试
def work(factory):
keyborad = factory.produce_keyboard() # 工厂制作键盘
mouse = factory.produce_mouse() # 工厂制作鼠标
keyborad.show() # 查看键盘信息
mouse.show() # 查看鼠标信息
if __name__ == '__main__':
# 创造Mika工厂,让它运行工作
factory = MikaFactory()
work(factory)
# 创建Piki工厂,让它运行工作
factory = PikiFactory()
work(factory)
建造者模式
"""
小明想要给自己的"戴尔"电脑外接一些设备:Mika鼠标、Piki键盘
小花想要给自己的"联想"电脑外接一些设备:Piki鼠标、Mika键盘
1. 找到技术人员告诉需求
2. 技术员工进行组装
3. 检查组装情况
"""
from abc import ABC, abstractmethod
# 组装电脑(抽象)
class AssembleComputer(ABC):
@abstractmethod
def install_mouse(self, brand): # 安装鼠标(抽象)
pass
@abstractmethod
def install_keyboard(self, brand): # 安装键盘(抽象)
pass
@abstractmethod
def show(self): # 查看组装的状态(抽象)
pass
# 组装"戴尔"电脑(具体)
class AssembleDellComputer(AssembleComputer):
def __init__(self):
self.__installation_list = [] # 安装列表,用来记录当前已经成功安装了的组件
def install_mouse(self, brand):
self.__installation_list.append(f"{brand}鼠标")
print(f"已安装:{brand}鼠标")
def install_keyboard(self, brand):
self.__installation_list.append(f"{brand}键盘")
print(f"已安装:{brand}键盘")
def show(self):
print("此电脑的所有外接设备:", end="")
for item in self.__installation_list:
print(item, end=", ")
print()
# 组装"联想"电脑(具体)
class AssembleLenovoComputer(AssembleComputer):
def __init__(self):
self.__installation_list = [] # 安装列表,用来记录当前已经成功安装了的组件
def install_mouse(self, brand):
self.__installation_list.append(f"{brand}鼠标")
print(f"已安装:{brand}鼠标")
def install_keyboard(self, brand):
self.__installation_list.append(f"{brand}键盘")
print(f"已安装:{brand}键盘")
def show(self):
print("此电脑的所有外接设备:", end="")
for item in self.__installation_list:
print(item, end=", ")
print()
# 建造者(抽象)
class Builder(ABC):
def __init__(self, computer_type):
# self.product 里面保存(维护)着一个组装对象
if computer_type == "戴尔":
self._product = AssembleDellComputer()
elif computer_type == "联想":
self._product = AssembleLenovoComputer()
else:
raise "电脑类型错误!"
@abstractmethod
def install_mouse(self, brand):
pass
@abstractmethod
def install_keyboard(self, brand):
pass
@abstractmethod
def check(self):
pass
# 建造者(具体)————技术人员
class Technician(Builder):
# 技术人员安装鼠标
def install_mouse(self, brand):
print(f"技术人员正在安装{brand}鼠标...")
self._product.install_mouse(brand)
print(f"技术人员安装{brand}鼠标成功!")
# 技术人员安装键盘
def install_keyboard(self, brand):
print(f"技术人员正在安装{brand}键盘...")
self._product.install_keyboard(brand)
print(f"技术人员安装{brand}键盘成功!")
# 技术人员检查安装情况
def check(self):
print("技术人员正在检查设备的安装情况...")
print("技术人员检查完毕,安装结果如下:")
self._product.show()
if __name__ == '__main__':
# 创造一个负责组装戴尔电脑的技术人员
t1 = Technician("戴尔")
# 创造一个负责组装联想电脑的技术人员
t2 = Technician("联想")
# 小明告诉 t1 技术人员,组装 Mika鼠标、Piki键盘,技术人员根据要求进行安装
t1.install_mouse("Mika")
t1.install_keyboard("Piki")
# 小花告诉 t2 技术人员,组装 Piki鼠标、Mika键盘,技术人员根据要求进行安装
t2.install_mouse("Piki")
t2.install_keyboard("Mika")
# t1 技术人员检查组装情况
t1.check()
# t2 技术人员检查组装情况
t2.check()
原型模式
import copy # 导入copy模块,用于深度复制对象
# 定义一个名为 Prototype(原型)的类,用于管理对象的注册、注销和克隆
class Prototype:
def __init__(self):
self._objects = {} # 初始化一个字典来存储注册的对象,键为名称,值为对象实例
def register_object(self, name, obj):
"""
注册一个对象到_objects字典中
:param name: 对象的名称
:param obj: 要注册的对象实例
"""
self._objects[name] = obj
def unregister_object(self, name):
"""
从_objects字典中注销一个对象
:param name: 要注销的对象的名称
"""
del self._objects[name]
def clone(self, name, **attr):
"""
克隆一个已注册的对象,并更新其内部属性字典
:param name: 要克隆的对象的名称
:param attr: 要更新的属性字典,使用关键字参数传入
:return: 克隆并更新后的对象实例
"""
obj = copy.deepcopy(self._objects.get(name)) # 使用deepcopy进行深度复制,得到一个新的对象实例
obj.__dict__.update(attr) # 更新对象的__dict__属性,即更新其内部属性。 attr == {'a': 1, 'b': 2, 'c': 3}
return obj
def test():
# 定义一个类A,用于演示
class A:
def __str__(self):
return "I am A"
# 创建A的一个实例a
a = A()
# 创建一个Prototype实例,用于管理对象
prototype = Prototype()
# 将a注册到prototype中,名称为'a'
prototype.register_object('a', a)
# 克隆a并更新其内部属性,得到b
b = prototype.clone('a', a=1, b=2, c=3)
# 打印a的字符串表示
print(a)
# 打印b的内部属性字典
print(b.__dict__)
# 尝试打印b的属性a, b, c
print(b.a)
print(b.b)
print(b.c)
if __name__ == '__main__':
test()
补充说明:
-
原型模式(Prototype Pattern)是一种创建型设计模式,它允许一个对象通过复制其自身的内部状态来创建新的对象实例。
-
这种复制过程可以被称为“克隆”。
-
原型模式提供了一种不依赖于类的构造函数来创建对象实例的方式,而是使用现有的对象实例来创建新的对象。
原型模式的作用:
- 性能优化:当对象的创建过程非常复杂或者代价非常高时,使用原型模式可以避免重复执行这些复杂的操作,从而提高性能。通过克隆一个已经存在的对象,可以快速地生成新的对象实例。
- 避免子类的构造函数被频繁调用:在继承层次较深的场景下,频繁地调用子类的构造函数可能会带来性能问题。通过原型模式,可以避免这种情况,因为对象的创建是通过克隆来完成的。
- 动态扩展:由于原型模式允许在运行时动态地添加或删除对象,因此它可以支持动态扩展。这意味着可以根据需要动态地改变系统中对象的数量或类型。
- 简化对象创建:当对象创建涉及复杂的配置或设置时,原型模式可以提供一个更简单的创建对象的方式。通过克隆一个已经配置好的对象实例,可以快速地生成具有相同配置的新对象。
示例代码中的原型模式:
- 在示例代码中,
Prototype
类就是一个原型管理器的实现。 - 它维护了一个存储已注册对象的字典(
_objects
)。 - 通过
register_object()
方法可以将对象注册到字典中,通过unregister_object()
方法可以从字典中注销对象。 clone()
方法则用于克隆已注册的对象,并允许通过关键字参数来更新克隆对象的属性。- 这个示例代码中的
A
类是一个简单的类,用于演示原型模式的使用。 - 通过创建一个
A
类的实例a
,并将其注册到Prototype
实例中,然后调用clone()
方法来克隆a
并更新其属性,可以得到一个新的对象实例b
。 - 这个过程中,
a
和b
是独立的对象实例,但它们具有相同的初始状态(因为b
是a
的克隆),并且b
的属性可以被单独更新。
总结
创建型模式总结
- 单例模式:创建一个全局的对象
- 工厂方法模式:实现单个类的对象的创建
- 抽象工厂模式:实现多个类的对象的创建
- 建造者模式:实现复杂类的对象的创建
- 原型模式:实现自身类的克隆