Python 设计模式入门指南:23 种设计模式轻松学
欢迎来到 Python 设计模式的学习之旅!本书将带你了解设计模式的世界,帮助你编写更优雅、更可维护的代码。我们将按照创建型模式、结构型模式和行为型模式的顺序,逐一探索23种经典设计模式。
第一部分:创建型模式(5种)
创建型模式关注对象的创建,通过不同的方式来控制对象的生成,提高代码的灵活性和可扩展性。
1. 工厂方法模式
概念: 提供一个创建对象的接口,但由子类决定实例化哪一个类。
适用场景: 当你希望将对象的创建和使用解耦时。
示例代码:
# 形状接口
class Shape:
def draw(self):
pass
# 具体形状
class Circle(Shape):
def draw(self):
print("Drawing a circle")
class Square(Shape):
def draw(self):
print("Drawing a square")
# 工厂接口
class ShapeFactory:
def get_shape(self):
pass
# 具体工厂
class CircleFactory(ShapeFactory):
def get_shape(self):
return Circle()
class SquareFactory(ShapeFactory):
def get_shape(self):
return Square()
# 客户端代码
factory = CircleFactory()
shape = factory.get_shape()
shape.draw() # 输出:Drawing a circle
代码解释:
- 定义了一个
Shape
接口,包含draw()
方法。 - 创建了两个具体形状
Circle
和Square
,实现了Shape
接口。 - 定义了一个
ShapeFactory
工厂接口,包含get_shape()
方法。 - 创建了两个具体工厂
CircleFactory
和SquareFactory
,分别生产Circle
和Square
对象。 - 客户端代码通过工厂接口获取产品对象,并调用其方法。
2. 抽象工厂模式
概念: 提供一个接口来创建相关或依赖对象的家族。
适用场景: 当你有多个产品族,并且需要在运行时选择一个产品族时。
示例代码:
# 计算机部件接口
class CPU:
def process(self):
pass
class GPU:
def render(self):
pass
# 具体部件
class IntelCPU(CPU):
def process(self):
print("Processing with Intel CPU")
class NvidiaGPU(GPU):
def render(self):
print("Rendering with Nvidia GPU")
# 抽象工厂
class ComputerFactory:
def create_cpu(self):
pass
def create_gpu(self):
pass
# 具体工厂
class IntelFactory(ComputerFactory):
def create_cpu(self):
return IntelCPU()
def create_gpu(self):
return NvidiaGPU()
# 客户端代码
factory = IntelFactory()
cpu = factory.create_cpu()
gpu = factory.create_gpu()
cpu.process() # 输出:Processing with Intel CPU
gpu.render() # 输出:Rendering with Nvidia GPU
代码解释:
- 定义了
CPU
和GPU
抽象产品类。 - 创建了具体产品
IntelCPU
和NvidiaGPU
。 - 定义了
ComputerFactory
抽象工厂类,包含create_cpu()
和create_gpu()
方法。 - 创建了具体工厂
IntelFactory
,生产不同品牌的产品。 - 客户端代码通过工厂获取产品对象,并调用其方法。
3. 单例模式
概念: 确保一个类只有一个实例,并提供一个全局访问点。
适用场景: 当你需要确保一个类只有一个实例时。
使用 @cache
重写单例模式
我们可以使用 Python 的 functools.cache
装饰器来缓存函数的结果。通过将类的实例化过程放入一个函数中,并用 @cache
装饰该函数,我们可以确保只创建一个实例。
示例代码:
from functools import cache
@cache
def get_singleton():
class Singleton:
def __init__(self):
self.value = 0
def increment(self):
self.value += 1
return Singleton()
# 客户端代码
s1 = get_singleton()
s1.increment()
print(s1.value) # 输出:1
s2 = get_singleton()
print(s2.value) # 输出:1
s2.increment()
print(s1.value) # 输出:2
print(s2.value) # 输出:2
代码解释:
- 我们导入了
functools.cache
装饰器。 - 创建了一个名为
get_singleton
的函数,该函数负责创建并返回Singleton
类的实例。 - 使用
@cache
装饰get_singleton
函数,确保该函数只返回第一次调用时创建的实例。 - 在客户端代码中,我们调用了
get_singleton()
函数两次,但实际创建的只有一个Singleton
实例。 - 对其中一个实例进行操作,另一个实例也会受到影响,因为它们指向同一个对象。
注意:
@cache
装饰器适用于不可变对象,如果Singleton
类的实例是可变的,需要确保对实例的修改不会导致意外的行为。@cache
装饰器在 Python 3.9 及以上版本中可用。
4. 建造者模式
概念: 将复杂对象的构建步骤分离,允许不同的建造者创建不同配置的对象。
适用场景: 当你需要构建复杂对象,并希望构建过程可以灵活组合时。
示例代码:
# 产品类
class Pizza:
def __init__(self):
self.parts = []
def add_part(self, part):
self.parts.append(part)
def display(self):
print("Pizza with parts:", self.parts)
# 建造者接口
class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()
def add_dough(self):
pass
def add_sauce(self):
pass
def add_topping(self):
pass
def get_pizza(self):
return self.pizza
# 具体建造者
class MargheritaBuilder(PizzaBuilder):
def add_dough(self):
self.pizza.add_part("thin dough")
def add_sauce(self):
self.pizza.add_part("tomato sauce")
def add_topping(self):
self.pizza.add_part("mozzarella cheese")
class PepperoniBuilder(PizzaBuilder):
def add_dough(self):
self.pizza.add_part("thick dough")
def add_sauce(self):
self.pizza.add_part("bbq sauce")
def add_topping(self):
self.pizza.add_part("pepperoni")
# 指挥者
class Director:
def construct(self, builder):
builder.add_dough()
builder.add_sauce()
builder.add_topping()
return builder.get_pizza()
# 客户端代码
director = Director()
builder = MargheritaBuilder()
pizza = director.construct(builder)
pizza.display() # 输出:Pizza with parts: ['thin dough', 'tomato sauce', 'mozzarella cheese']
builder = PepperoniBuilder()
pizza = director.construct(builder)
pizza.display() # 输出:Pizza with parts: ['thick dough', 'bbq sauce', 'pepperoni']
代码解释:
- 定义了
Pizza
产品类,包含parts
列表和相关方法。 - 定义了
PizzaBuilder
建造者接口,包含构建步骤的方法。 - 创建了具体建造者
MargheritaBuilder
和PepperoniBuilder
,实现了不同的构建步骤。 - 定义了
Director
指挥者类,负责调用建造者的方法来构建产品。 - 客户端代码通过指挥者和不同建造者创建不同的披萨。
5. 原型模式
概念: 通过克隆已有的对象来创建新对象,避免重复创建相同对象。
适用场景: 当对象的创建成本较高,或者需要大量相似对象时。
示例代码:
import copy
# 原型类
class Shape:
def __init__(self, x, y):
self.x = x
self.y = y
def clone(self):
return copy.deepcopy(self)
# 具体原型
class Circle(Shape):
def __init__(self, x, y, radius):
super().__init__(x, y)
self.radius = radius
def draw(self):
print(f"Drawing Circle at ({
self.x}, {
self.y}) with radius {
self.radius}")
# 客户端代码
original = Circle(0, 0, 5)
original.draw() # 输出:Drawing Circle at (0, 0) with radius 5
clone1 = original.clone()
clone1.draw() # 输出:Drawing Circle at (0, 0) with radius 5
clone2
标签:23,Python,self,模式,add,设计模式,class,def,pizza
From: https://blog.csdn.net/engchina/article/details/144654395