当前位置: 首页 > backend >正文

基于Python的设计模式之创建型模型

文章目录

    • 设计模式概述
    • 设计模式的基础
    • 设计模式的六大原则
    • 创建型模式
      • 单例模式
      • 简单工厂模式
      • 工厂方法模式
      • 抽象工厂模式
      • 建造者模式
      • 原型模式
    • 创建型模式小结

在这里插入图片描述

设计模式概述

设计模式(GOF,即 Gang of Four,四人组提出的经典设计模式)是面向对象系统中对重要且重复出现的设计进行系统化总结的方案。它包含模式名称、问题、解决方法和效果这四个基本要素,有助于开发者更高效地设计和构建软件系统。

设计模式的基础

  • 对象/类:面向对象编程的三大特性——封装、继承和多态是设计模式的基石。封装将数据和操作封装在一起,继承允许子类继承父类的属性和方法,多态则使得不同的对象可以对同一消息做出不同的响应。
  • 接口:接口是一种特殊的类,规定了继承它的类必须实现的方法。在 Python 中,有两种常见的实现方式:
    • 使用 NotImplementedError:通过在基类方法中抛出 NotImplementedError 异常,强制子类实现该方法。
    • 使用 abc 模块:利用 ABCMeta 元类和 @abstractmethod 装饰器,明确声明抽象方法,使类成为抽象基类。

设计模式的六大原则

  • 开闭原则:软件实体应该对扩展开放,对修改关闭。这意味着在不修改现有代码的情况下,能够通过扩展来添加新的功能。
  • 里氏替换原则:所有引用基类的方法必须能够透明地使用其子类的对象。即子类可以替换父类,而不会影响程序的正确性。
  • 依赖倒置原则:高层模块不应依赖低层模块,二者都应依赖于抽象。通过依赖抽象,可以降低模块之间的耦合度。
  • 接口隔离原则:使用多个专门的接口,而不是单一的总接口。这样可以避免类实现不必要的方法,提高代码的内聚性。
  • 迪米特法则:软件实体应尽可能少地与其他实体发生相互作用,以降低耦合度。
  • 单一职责原则:一个类应该只有一个导致其变更的原因。每个类应该只负责一项职责,提高代码的可维护性。

创建型模式

单例模式

  • 定义:确保一个类只有一个实例,并提供一个全局访问点。
  • 适用场景:当类只能有一个实例,并且需要全局访问时,如配置管理类、日志记录器等。
  • 优点:对唯一实例的受控访问,避免命名空间污染。
  • 示例代码
class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if cls._instance is None:cls._instance = super().__new__(cls)return cls._instance# 测试单例模式
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2)  # 输出: True

简单工厂模式

  • 定义:通过一个工厂类负责创建产品类的实例,而不直接向客户端暴露对象创建的实现细节。
  • 优点:隐藏了对象创建的实现细节,客户端无需修改代码。
  • 缺点:违反单一职责原则,添加新产品时需修改工厂类代码。
  • 示例代码
from abc import abstractmethod, ABCMetaclass Payment(metaclass=ABCMeta):@abstractmethoddef pay(self, money):passclass Alipay(Payment):def pay(self, money):print(f'支付宝支付 {money} 元')class PaymentFactory:def create_payment(self, method):if method == 'alipay':return Alipay()else:raise ValueError(f'未知支付方式: {method}')factory = PaymentFactory()
payment = factory.create_payment('alipay')
payment.pay(100)

工厂方法模式

  • 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个产品类。
  • 适用场景:需要生产多种复杂对象时,降低耦合度。
  • 示例代码
from abc import abstractmethod, ABCMetaclass Payment(metaclass=ABCMeta):@abstractmethoddef pay(self, money):passclass Alipay(Payment):def pay(self, money):print(f'支付宝支付 {money} 元')class PaymentFactory(metaclass=ABCMeta):@abstractmethoddef create_payment(self):passclass AlipayFactory(PaymentFactory):def create_payment(self):return Alipay()factory = AlipayFactory()
payment = factory.create_payment()
payment.pay(100)

抽象工厂模式

  • 定义:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
  • 适用场景:系统要独立于产品创建与组合时。
  • 示例代码
from abc import abstractmethod, ABCMetaclass PhoneShell(metaclass=ABCMeta):@abstractmethoddef get_shell_info(self):passclass MiPhoneShell(PhoneShell):def get_shell_info(self):return '小米手机壳'class PhoneFactory(metaclass=ABCMeta):@abstractmethoddef make_shell(self):passclass MiFactory(PhoneFactory):def make_shell(self):return MiPhoneShell()factory = MiFactory()
shell = factory.make_shell()
print(shell.get_shell_info())

建造者模式

  • 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 适用场景:当创建复杂对象的算法应独立于该对象的组成部分时。
  • 示例代码
class Player:def __init__(self, face=None, body=None):self.face = faceself.body = bodydef __str__(self):return f'Player with {self.face} face and {self.body} body'class PlayerBuilder:def build_face(self):passdef build_body(self):passdef get_player(self):passclass BeautifulWomanBuilder(PlayerBuilder):def build_face(self):return '漂亮脸蛋'def build_body(self):return '苗条身材'def get_player(self):face = self.build_face()body = self.build_body()return Player(face, body)builder = BeautifulWomanBuilder()
player = builder.get_player()
print(player)

原型模式

  • 定义:通过复制现有对象来创建新对象,而不是通过实例化类。
  • 适用场景:当创建对象的成本较高,或者需要创建多个相似对象时。
  • 示例代码
import copyclass Prototype:def clone(self):return copy.deepcopy(self)class ConcretePrototype(Prototype):def __init__(self, value):self.value = valuedef __str__(self):return str(self.value)# 创建原型对象
prototype = ConcretePrototype(10)# 克隆对象
clone = prototype.clone()print(prototype)  # 输出: 10
print(clone)      # 输出: 10

创建型模式小结

使用抽象工厂、原型或建造者模式的设计通常比工厂方法模式更灵活,但也更复杂。设计者通常从工厂方法开始,随着需求的变化,逐步演化到其他创建模式。了解多种模式可以为设计提供更多选择,根据具体的应用场景选择合适的设计模式,能够提高软件的可维护性、可扩展性和可复用性。

在这里插入图片描述

http://www.xdnf.cn/news/827.html

相关文章:

  • 动手学深度学习——Transformer
  • 14.第二阶段x64游戏实战-分析人物的名字
  • Github 热点项目 Jumpserver开源堡垒机让服务器管理效率翻倍
  • 25.解决中医知识问答删除历史对话功能后端处理请求时抛出异常
  • 前端基础之《Vue(7)—生命周期》
  • 深度学习算法:从基础到实践
  • 第 28 场 蓝桥月赛
  • android framework开发的技能要求
  • HarmonyOS 笔记
  • Linux命令--将控制台的输入写入文件
  • Java编程基础(第三篇:初见静态方法)
  • 网络操作系统与应用服务器
  • Linux教程-Shell编程系列一
  • 算法—选择排序—js(场景:简单实现,不关心稳定性)
  • day1 python训练营
  • 嵌入式芯片中的 SRAM 内容细讲
  • JavaScript 一维数组转不含零的两个数
  • 专题十七:NAT技术
  • TS—抽象类
  • 英语学习4.15
  • Linux常见指令解析(二)
  • 坐标轴QCPAxis
  • 集成运放的关键技术参数
  • AutoSAR从概念到实践系列之MCAL篇(二)——Mcu模块配置及代码详解(上)
  • 20.3 使用技巧6
  • 【统计分析120】统计分析120题分享
  • 字节跳动发布UI-TARS-1.5,入门AI就来近屿智能
  • using用法整理
  • 海拔与大气压关系,大气压单位,气压传感器对比
  • RV1126网络环境TFTPNFS搭建(三)