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

代码解释:

  1. 定义了一个Shape接口,包含draw()方法。
  2. 创建了两个具体形状CircleSquare,实现了Shape接口。
  3. 定义了一个ShapeFactory工厂接口,包含get_shape()方法。
  4. 创建了两个具体工厂CircleFactorySquareFactory,分别生产CircleSquare对象。
  5. 客户端代码通过工厂接口获取产品对象,并调用其方法。
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

代码解释:

  1. 定义了CPUGPU抽象产品类。
  2. 创建了具体产品IntelCPUNvidiaGPU
  3. 定义了ComputerFactory抽象工厂类,包含create_cpu()create_gpu()方法。
  4. 创建了具体工厂IntelFactory,生产不同品牌的产品。
  5. 客户端代码通过工厂获取产品对象,并调用其方法。
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

代码解释:

  1. 我们导入了 functools.cache 装饰器。
  2. 创建了一个名为 get_singleton 的函数,该函数负责创建并返回 Singleton 类的实例。
  3. 使用 @cache 装饰 get_singleton 函数,确保该函数只返回第一次调用时创建的实例。
  4. 在客户端代码中,我们调用了 get_singleton() 函数两次,但实际创建的只有一个 Singleton 实例。
  5. 对其中一个实例进行操作,另一个实例也会受到影响,因为它们指向同一个对象。

注意:

  • @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']

代码解释:

  1. 定义了Pizza产品类,包含parts列表和相关方法。
  2. 定义了PizzaBuilder建造者接口,包含构建步骤的方法。
  3. 创建了具体建造者MargheritaBuilderPepperoniBuilder,实现了不同的构建步骤。
  4. 定义了Director指挥者类,负责调用建造者的方法来构建产品。
  5. 客户端代码通过指挥者和不同建造者创建不同的披萨。
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()  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值