【Python设计模式精讲】:从入门到精通,9种常用模式一网打尽

部署运行你感兴趣的模型镜像

第一章:Python设计模式概述

设计模式是软件开发中针对常见问题的可重用解决方案,它们不依赖于具体语言,但在 Python 中因其动态特性和简洁语法而展现出独特优势。掌握设计模式有助于提升代码的可维护性、可扩展性和可读性。

设计模式的三大分类

  • 创建型模式:关注对象的创建机制,如单例模式、工厂模式。
  • 结构型模式:处理类或对象的组合,如适配器模式、装饰器模式。
  • 行为型模式:定义对象间的通信方式,如观察者模式、策略模式。

Python中的单例模式实现

单例模式确保一个类只有一个实例,并提供全局访问点。在 Python 中可通过重写 __new__ 方法实现:

class Singleton:
    _instance = None  # 存储唯一实例

    def __new__(cls):
        if cls._instance is None:
            # 仅在实例不存在时创建
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

# 使用示例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # 输出: True,证明为同一实例

常用设计模式对比

模式名称适用场景优点
工厂模式对象创建逻辑复杂时解耦创建与使用
装饰器模式动态添加功能避免继承爆炸
观察者模式事件通知系统实现松耦合通信
graph TD A[客户端] --> B(调用工厂) B --> C{创建对象} C --> D[具体产品A] C --> E[具体产品B]

第二章:创建型设计模式详解

2.1 单例模式:确保类的唯一实例

单例模式是一种创建型设计模式,用于确保一个类在整个应用程序生命周期中仅存在一个实例,并提供一个全局访问点。
实现原理
通过私有化构造函数防止外部直接实例化,同时在类内部持有一个静态实例引用,并提供公共静态方法获取该实例。
package singleton

import "sync"

type Singleton struct{}

var (
	instance *Singleton
	once     sync.Once
)

func GetInstance() *Singleton {
	once.Do(func() {
		instance = &Singleton{}
	})
	return instance
}
上述 Go 语言代码使用 sync.Once 确保并发安全的单例初始化。其中 once.Do() 保证初始化逻辑仅执行一次,instance 为私有变量,避免外部修改。
典型应用场景
  • 配置管理器
  • 日志记录器
  • 数据库连接池

2.2 工厂方法模式:定义创建对象的接口

工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定实例化哪个类。该模式将对象的创建延迟到子类中实现,从而提升系统的可扩展性与解耦程度。
核心结构
主要包含四个角色:
  • Product:定义产品接口
  • ConcreteProduct:具体产品实现
  • Creator:声明工厂方法
  • ConcreteCreator:实现工厂方法以返回具体产品
代码示例
type Product interface {
    GetName() string
}

type ConcreteProductA struct{}

func (p *ConcreteProductA) GetName() string {
    return "Product A"
}

type Creator interface {
    FactoryMethod() Product
}

type ConcreteCreatorA struct{}

func (c *ConcreteCreatorA) FactoryMethod() Product {
    return &ConcreteProductA{}
}
上述代码中,Creator 接口定义了 FactoryMethod(),返回一个 Product 类型。具体创建逻辑由 ConcreteCreatorA 实现,调用时无需了解具体产品类型,仅依赖抽象接口即可完成对象构建,增强了模块间的松耦合性。

2.3 抽象工厂模式:创建一系列相关对象

抽象工厂模式用于创建一组相关或依赖对象的家族,而无需指定具体类。它通过定义一个创建产品族的接口,使得客户端与具体实现解耦。
核心结构
  • 抽象工厂(Abstract Factory):声明创建一系列产品的方法
  • 具体工厂(Concrete Factory):实现创建具体产品族的逻辑
  • 抽象产品(Abstract Product):定义产品的接口
  • 具体产品(Concrete Product):工厂创建的实际对象
代码示例
type GUIFactory interface {
    CreateButton() Button
    CreateCheckbox() Checkbox
}

type WindowsFactory struct{}

func (f *WindowsFactory) CreateButton() Button {
    return &WindowsButton{}
}
func (f *WindowsFactory) CreateCheckbox() Checkbox {
    return &WindowsCheckbox{}
}
上述代码定义了一个 GUI 抽象工厂,可生成按钮和复选框。WindowsFactory 实现该接口,返回 Windows 风格的具体控件。客户端通过工厂接口编程,无需关心对象创建细节,便于扩展新主题(如 macOS 工厂)。

2.4 建造者模式:分步构建复杂对象

核心思想与适用场景
建造者模式用于将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。它适用于包含多个组成部分的复杂对象,且构造过程步骤稳定但参数多变。
  • 避免构造函数参数爆炸
  • 提升代码可读性和可维护性
  • 支持不可变对象的逐步构建
Go语言实现示例

type Computer struct {
    CPU, GPU string
    RAMSize int
}

type ComputerBuilder struct {
    computer Computer
}

func (b *ComputerBuilder) SetCPU(cpu string) *ComputerBuilder {
    b.computer.CPU = cpu
    return b
}

func (b *ComputerBuilder) SetGPU(gpu string) *ComputerBuilder {
    b.computer.GPU = gpu
    return b
}

func (b *ComputerBuilder) SetRAM(ram int) *ComputerBuilder {
    b.computer.RAMSize = ram
    return b
}

func (b *ComputerBuilder) Build() Computer {
    return b.computer
}
上述代码通过链式调用逐步设置属性,最终调用 Build() 返回完整对象。每个设置方法返回构建器自身,便于连续调用。该方式清晰表达了构建流程,避免了冗长的构造函数,并支持灵活扩展。

2.5 原型模式:通过克隆提高创建效率

在对象创建成本较高的场景中,原型模式通过复制现有实例来避免重复初始化过程,显著提升性能。该模式的核心是定义一个克隆接口,使对象能自我复制。
克隆机制实现
type Prototype interface {
    Clone() Prototype
}

type ConcretePrototype struct {
    Data []int
}

func (p *ConcretePrototype) Clone() Prototype {
    copy := *p
    copy.Data = make([]int, len(p.Data))
    copy(copy.Data, p.Data)
    return ©
}
上述代码中,Clone() 方法复制结构体并深拷贝引用类型字段,确保原始对象与克隆对象互不影响。
使用优势
  • 避免重复执行复杂构造逻辑
  • 运行时动态加载和复制对象
  • 简化对象创建接口

第三章:结构型设计模式解析

3.1 适配器模式:兼容不匹配的接口

适配器模式用于解决接口不兼容的问题,通过封装一个类的接口,使其与另一个期望的接口匹配。它常用于集成第三方库或遗留系统。
基本结构
适配器模式包含三个核心角色:目标接口(Target)、被适配者(Adaptee)和适配器(Adapter)。适配器将Adaptee的接口转换为客户端期望的Target接口。
代码示例

type Target interface {
    Request() string
}

type Adaptee struct{}

func (a *Adaptee) SpecificRequest() string {
    return "Adaptee method"
}

type Adapter struct {
    adaptee *Adaptee
}

func (ad *Adapter) Request() string {
    return ad.adaptee.SpecificRequest()
}
上述代码中,Adaptee 提供了特定方法,但接口不匹配。适配器 Adapter 实现了 Target 接口,并在内部调用 Adaptee 的方法,完成接口转换。

3.2 装饰器模式:动态添加功能特性

装饰器模式是一种结构型设计模式,允许在不修改原有对象逻辑的前提下,动态地为其添加新的功能。它通过组合的方式,将功能分散到独立的装饰类中,实现关注点分离。
核心思想
装饰器模式依赖于抽象组件接口,具体组件和装饰器均实现该接口。多个装饰器可层层嵌套,形成责任链式调用。
代码示例

type Component interface {
    Operation() string
}

type ConcreteComponent struct{}

func (c *ConcreteComponent) Operation() string {
    return "Basic operation"
}

type Decorator struct {
    component Component
}

func (d *Decorator) Operation() string {
    return "Enhanced: " + d.component.Operation()
}
上述代码中,Decorator 持有一个 Component 接口实例,可在调用前后插入额外逻辑。通过组合而非继承扩展行为,提升了灵活性与可维护性。
应用场景
  • 日志记录、权限校验等横切关注点
  • 中间件系统中的请求处理链
  • GUI组件的功能增强

3.3 代理模式:控制对象的访问方式

代理模式是一种结构型设计模式,用于为其他对象提供一种间接访问机制,在不改变原始类的前提下增强或控制其行为。
核心结构与角色
代理模式包含三个关键角色:
  • Subject(抽象主题):定义真实对象和代理对象的公共接口;
  • RealSubject(真实主题):具体业务逻辑的执行者;
  • Proxy(代理):持有真实对象的引用,可附加访问控制、延迟加载等逻辑。
代码示例:Go 中的虚拟代理实现

type Image interface {
    Display()
}

type RealImage struct {
    filename string
}

func (r *RealImage) LoadFromDisk() {
    fmt.Printf("Loading %s from disk\n", r.filename)
}

func (r *RealImage) Display() {
    fmt.Printf("Displaying %s\n", r.filename)
}

type ProxyImage struct {
    realImage *RealImage
    filename  string
}

func (p *ProxyImage) Display() {
    if p.realImage == nil {
        p.realImage = &RealImage{filename: p.filename}
        p.realImage.LoadFromDisk()
    }
    p.realImage.Display()
}
上述代码中,ProxyImage 延迟创建 RealImage 实例,仅在真正需要时才加载资源,有效优化性能。代理对象封装了创建逻辑,调用方无需感知内部延迟加载机制。

第四章:行为型设计模式实战

4.1 观察者模式:实现事件订阅机制

观察者模式是一种行为设计模式,允许你定义一个订阅机制,使多个观察者对象监听某个主题对象的状态变化。当主题状态发生变化时,所有注册的观察者都会自动收到通知。
核心结构与角色
  • Subject(主题):维护观察者列表,提供注册与注销接口。
  • Observer(观察者):定义接收更新通知的接口。
  • ConcreteObserver:实现具体的通知处理逻辑。
代码实现示例
type Subject struct {
    observers []func(string)
}

func (s *Subject) Subscribe(observer func(string)) {
    s.observers = append(s.observers, observer)
}

func (s *Subject) Notify(event string) {
    for _, obs := range s.observers {
        obs(event)
    }
}
上述 Go 示例中,Subscribe 方法用于添加监听函数,Notify 遍历所有监听者并传递事件数据,实现松耦合的事件通信机制。

4.2 策略模式:封装可互换的算法族

策略模式用于将一组可互换的算法封装在独立的类中,使它们可以动态切换,而无需修改客户端逻辑。该模式的核心是定义统一的策略接口,各个具体策略实现该接口。
核心结构
  • Strategy 接口:声明算法的公共操作;
  • ConcreteStrategy:实现具体算法;
  • Context:持有策略实例并委托执行。
代码示例(Go)
type PaymentStrategy interface {
    Pay(amount float64) string
}

type CreditCardStrategy struct{}

func (c *CreditCardStrategy) Pay(amount float64) string {
    return fmt.Sprintf("Paid %.2f via Credit Card", amount)
}

type PayPalStrategy struct{}

func (p *PayPalStrategy) Pay(amount float64) string {
    return fmt.Sprintf("Paid %.2f via PayPal", amount)

type PaymentContext struct {
    strategy PaymentStrategy
}

func (p *PaymentContext) SetStrategy(s PaymentStrategy) {
    p.strategy = s
}

func (p *PaymentContext) ExecutePayment(amount float64) string {
    return p.strategy.Pay(amount)
}
上述代码中,PaymentStrategy 定义了支付行为的统一接口,CreditCardStrategyPayPalStrategy 提供不同实现。通过 PaymentContext 动态设置策略,实现解耦。

4.3 命令模式:将请求封装为对象

命令模式是一种行为设计模式,它将请求封装成独立的对象,从而使你可以用不同的请求、队列或日志来参数化其他对象。
核心结构与角色
  • Command:声明执行操作的接口
  • ConcreteCommand:实现具体请求的执行逻辑
  • Invoker:调用命令对象执行请求
  • Receiver:真正执行请求的对象
代码示例
type Command interface {
    Execute()
}

type LightOnCommand struct {
    light *Light
}

func (c *LightOnCommand) Execute() {
    c.light.TurnOn()
}
上述代码定义了一个打开灯的命令。LightOnCommand 持有对 Light(接收者)的引用,并在 Execute 方法中调用其行为。通过将“开灯”这一动作封装为对象,可以在运行时动态传递、撤销或记录该请求,提升了系统的灵活性与解耦程度。

4.4 模板方法模式:定义算法骨架结构

模板方法模式属于行为型设计模式,它在抽象类中定义一个算法的骨架,将部分步骤延迟到子类中实现。该模式通过继承实现代码复用,同时保持算法结构不变。
核心结构与角色
  • 抽象类(AbstractClass):定义算法的模板方法及抽象操作
  • 具体类(ConcreteClass):实现抽象类中的具体步骤
代码示例

abstract class DataProcessor {
    // 模板方法,定义算法骨架
    public final void process() {
        readData();
        parseData();
        validateData();
        saveData();
    }
    
    abstract void readData();
    abstract void parseData();
    
    // 钩子方法,可选覆盖
    boolean validateData() { return true; }
    
    void saveData() {
        System.out.println("Saving data...");
    }
}
上述代码中,process() 方法为模板方法,封装了固定的数据处理流程。子类只需实现 readData()parseData(),无需改变整体执行逻辑,从而实现算法结构的统一与行为的灵活扩展。

第五章:设计模式综合应用与最佳实践

构建可扩展的支付系统
在现代电商平台中,支付模块需支持多种渠道(如支付宝、微信、银联)。结合策略模式与工厂模式可实现灵活扩展:

type PaymentStrategy interface {
    Pay(amount float64) string
}

type Alipay struct{}
func (a *Alipay) Pay(amount float64) string {
    return fmt.Sprintf("支付宝支付 %.2f 元", amount)
}

type PaymentFactory struct{}
func (f *PaymentFactory) GetPayment(method string) PaymentStrategy {
    switch method {
    case "alipay":
        return &Alipay{}
    case "wechat":
        return &WechatPay{}
    default:
        panic("不支持的支付方式")
    }
}
日志系统的观察者与单例组合
日志模块通常作为全局服务存在,使用单例确保唯一实例,同时通过观察者模式通知多个处理器(如文件、数据库、远程服务):
  • Logger 单例维护订阅者列表
  • 每当日志事件触发,调用所有 Observer 的 Update 方法
  • FileLogger 和 AlertLogger 可独立处理不同级别日志
微服务中的模式协同
在订单服务中,使用模板方法定义创建流程,钩子方法允许子类定制库存扣减与积分计算逻辑。配合依赖注入容器管理各策略实例,提升测试性与解耦程度。
模式用途优势
策略 + 工厂支付方式动态切换新增渠道无需修改核心逻辑
观察者 + 单例日志分发多目标异步处理
用户请求 → 工厂创建策略 → 执行对应支付 → 日志发布事件 → 多个监听器响应

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值