Python之常用设计模式(创建型模式篇)
2021/6/20 17:24:06
本文主要是介绍Python之常用设计模式(创建型模式篇),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Python之常用设计模式
一、设计模式分类
1. 创建型模式
工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式
2. 结构型模式
适配器模式、桥模式、组合模式、装饰模式、外观模式、享元模式、代理模式
3. 行为型模式
解释器模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式、模板方法模式
二、创建型模式
1. 简单工厂模式
-
内容
- 不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
-
角色(类)
- 工厂角色(Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): pass class AliPay(Payment): def __init__(self, use_huabei=False) -> None: self.use_huabei = use_huabei def pay(self, money): if self.use_huabei: print(f"花呗支付{money}元") else: print(f"支付宝余额支付{money}元") class WechatPay(Payment): def pay(self, money): print(f"微信支付{money}元") class PaymentFactory: """生产支付对象的工厂类 用于生产AliPay或WechatPay对象""" def createPayment(self, method): if method == "alipay": return AliPay() elif method == "huabei": return AliPay(use_huabei=True) elif method == "wechat": return WechatPay() else: raise TypeError(f"No such payment named {method}") # client pf = PaymentFactory() p = pf.createPayment("huabei") p.pay(100)
上面例子中,工厂角色(类)是PaymentFactory,抽象产品角色是Payment,具体产品角色是AliPay和WechatPay。
- 优点
- 隐藏了对象创建的实现细节
- 客户端不需要修改代码
- 缺点
- 违反了单一职责原则,将创建逻辑几种到一个工厂类里
- 当添加新产品时,需要修改工厂类代码,违反了开闭原则
2. 工厂方法模式
- 内容
定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
- 角色
- 抽象工厂角色(Creator)
- 具体工厂角色(Concrete Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): pass class AliPay(Payment): def __init__(self, use_huabei=False) -> None: self.use_huabei = use_huabei def pay(self, money): if self.use_huabei: print(f"花呗支付{money}元") else: print(f"支付宝余额支付{money}元") class WechatPay(Payment): def pay(self, money): print(f"微信支付{money}元") class BankPay(Payment): def pay(self, money): print(f"银联支付{money}元") class PaymentFactory(metaclass=ABCMeta): @abstractmethod def createPayment(self): pass class AliPayFactory(PaymentFactory): def createPayment(self): return AliPay() class WechatPayFactory(PaymentFactory): def createPayment(self): return WechatPay() class HuaBeiFactory(PaymentFactory): def createPayment(self): return AliPay(use_huabei=True) class BankPayFactory(PaymentFactory): def createPayment(self): return BankPay() # client pf = HuaBeiFactory() p = pf.createPayment() p.pay(100)
上面例子中,抽象工厂角色是PaymentFactory,具体工厂角色是AliPayFactory、WechatPayFactory、HuaBeiFactory和BankPayFactory,抽象产品角色是Payment,具体产品角色是AliPay、WechatPay、BankPay。
- 优点
- 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
- 隐藏了对象创建的实现细节
- 缺点
- 每增加一个具体产品类,就必须增加一个相应的具体工厂类
3. 抽象工厂模式
- 内容
定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
举个例子:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
- 角色
- 抽象工厂角色(Creator)
- 具体工厂角色(Concrete Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
- 客户端(Client)
from abc import abstractmethod, ABCMeta # 抽象产品 class PhoneShell(metaclass=ABCMeta): @abstractmethod def show_shell(self): pass class CPU(metaclass=ABCMeta): @abstractmethod def show_cpu(self): pass class OS(metaclass=ABCMeta): @abstractmethod def show_os(self): pass # 抽象工厂 class PhoneFactory(metaclass=ABCMeta): @abstractmethod def make_shell(self): pass @abstractmethod def make_cpu(self): pass @abstractmethod def make_os(self): pass # 具体产品 class SmallShell(PhoneShell): def show_shell(self): print("普通手机小手机壳") class BigShell(PhoneShell): def show_shell(self): print("普通手机大手机壳") class AppleShell(PhoneShell): def show_shell(self): print("苹果手机壳") class MediaTekCPU(CPU): def show_cpu(self): print("联发科CPU") class SnapDragonCPU(CPU): def show_cpu(self): print("骁龙CPU") class AppleCPU(CPU): def show_cpu(self): print("苹果CPU") class Android(OS): def show_os(self): print("Android系统") class IOS(OS): def show_os(self): print("IOS系统") # 具体工厂 class MiFactory(PhoneFactory): def make_shell(self): return BigShell() def make_cpu(self): return SnapDragonCPU() def make_os(self): return Android() class IPhoneFactory(PhoneFactory): def make_shell(self): return AppleShell() def make_cpu(self): return AppleCPU() def make_os(self): return IOS() # 客户端 class Phone(): def __init__(self, cpu, os, shell) -> None: self.cpu = cpu self.os = os self.shell = shell def show_info(self): print("手机信息:") self.cpu.show_cpu() self.os.show_os() self.shell.show_shell() def make_phone(factory): cpu = factory.make_cpu() os = factory.make_os() shell = factory.make_shell() return Phone(cpu, os, shell) p1 = make_phone(MiFactory()) p1.show_info()
- 优点
- 将客户端与类的具体实现相分离
- 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
- 有利于产品的一致性(即产品之间的约束关系)
- 缺点
- 难以支持新种类的(抽象)产品
4. 建造者模式
- 内容
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
- 角色
- 抽象建造者(Builder)
- 具体建造者(Concrete Builder)
- 指挥者(Director)
- 产品(Product)
from abc import abstractmethod, ABCMeta class Player(): """产品""" def __init__(self, face=None, body=None, arm=None, leg=None) -> None: self.face = face self.body = body self.arm = arm self.leg = leg def __str__(self) -> str: return f"{self.face},{self.body},{self.arm},{self.leg}" class PlayerBuilder(metaclass=ABCMeta): """抽象建造者""" @abstractmethod def build_face(self): pass @abstractmethod def build_body(self): pass @abstractmethod def build_arm(self): pass @abstractmethod def build_leg(self): pass class SexyGirlBuilder(PlayerBuilder): """具体建造者""" def __init__(self) -> None: self.player = Player() def build_face(self): self.player.face = "漂亮脸蛋" def build_body(self): self.player.body = "苗条" def build_arm(self): self.player.arm = "漂亮胳膊" def build_leg(self): self.player.leg = "大长腿" class MonsterBuilder(PlayerBuilder): """具体建造者""" def __init__(self) -> None: self.player = Player() def build_face(self): self.player.face = "怪兽脸" def build_body(self): self.player.body = "怪兽身材" def build_arm(self): self.player.arm = "长毛的胳膊" def build_leg(self): self.player.leg = "长毛的腿" class PlayerDirector(): """指挥者 控制组装顺序""" def builder_player(self, builder): builder.build_body() builder.build_face() builder.build_arm() builder.build_leg() return builder.player # client builder = SexyGirlBuilder() director = PlayerDirector() p = director.builder_player(builder) print(p)
建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
- 优点
- 隐藏了一个产品的内部结构和装配过程
- 将构造代码与表示代码分开
- 可以对构造过程进行更精细的控制
5. 单例模式
- 内容
保证一个类只有一个实例,并提供一个访问它的全局访问点。
- 角色
单例(Singleton)
from abc import abstractmethod, ABCMeta class Singleton: def __new__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): cls._instance = super(Singleton, cls).__new__(cls) return cls._instance class MyClass(Singleton): def __init__(self, a) -> None: self.a = a a = MyClass(10) b = MyClass(20) print(a.a) # 20 print(b.a) # 20
- 优点
- 对唯一实例的受控访问
- 单例相当于全局变量,但防止了命名空间被污染
6. 创建型模式总结
- 抽象工厂模式和建造者模式相比于简单工厂模式和工厂方法模式而言更灵活也更复杂。
- 通常情况下、设计以简单工厂模式或工厂方法模式开始,当你发现设计需要更大的灵活性时,则像更复杂的设计模式演化。
这篇关于Python之常用设计模式(创建型模式篇)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-23使用python部署一个usdt合约,部署自己的usdt稳定币
- 2024-12-20Python编程入门指南
- 2024-12-20Python编程基础与进阶
- 2024-12-19Python基础编程教程
- 2024-12-19python 文件的后缀名是什么 怎么运行一个python文件?-icode9专业技术文章分享
- 2024-12-19使用python 把docx转为pdf文件有哪些方法?-icode9专业技术文章分享
- 2024-12-19python怎么更换换pip的源镜像?-icode9专业技术文章分享
- 2024-12-19Python资料:新手入门的全面指南
- 2024-12-19Python股票自动化交易实战入门教程
- 2024-12-19Python股票自动化交易入门教程