Python常见设计模式1: 创建型模式
文章目录
- 简单工厂模式
- 工厂模式
- 抽象工厂模式
- 建造者模式
- 单例模式
简单工厂模式
不属于GOF最初提出的23种设计模式,但也很常见,使用起来较为便捷。
- 不直接向客户暴露对象的实现细节,而是通过一个工厂类来负责创建产品的实例。
- 角色:
- 工厂角色(Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):# abstract class@abstractmethoddef pay(self, money):passclass Alipay(Payment):def __init__(self, use_huabei=False):self.use_huabei = use_huabeidef pay(self, money):if self.use_huabei:print("花呗支付%d元。" % money)else:print("支付宝支付%d元。" % money)class WechatPay(Payment):def pay(self, money):print("微信支付%d元。" % money)class PaymentFactory:@staticmethoddef create_payment(method):if method == 'alipay':return Alipay()elif method == 'huabei':return Alipay(use_huabei=True)elif method == 'wechat':return WechatPay()else:raise TypeError("No such payment named %s" % method)# client
pm = PaymentFactory.create_payment('huabei')
pm.pay(300)
工厂模式
- 定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
- 角色:
- 抽象工厂角色(Creator)
- 具体工厂角色(Concrete Creator)
- 抽象产品角色(Product)
- 具体产品角色(Contrete Product)
from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):# abstract class@abstractmethoddef pay(self, money):passclass Alipay(Payment):def __init__(self, use_huabei=False):self.use_huabei = use_huabeidef pay(self, money):if self.use_huabei:print("花呗支付%d元。" % money)else:print("支付宝支付%d元。" % money)class WechatPay(Payment):def pay(self, money):print("微信支付%d元。" % money)class YinlianPay(Payment):def pay(self, money):print("银联支付%d元。" % money)class PaymentFactory(metaclass=ABCMeta):@abstractmethoddef create_payment(self):passclass AlipayFactory(PaymentFactory):def create_payment(self):return Alipay()class WechatFactory(PaymentFactory):def create_payment(self):return WechatPay()class HuabeiFactory(PaymentFactory):def create_payment(self):return Alipay(use_huabei=True)class YinlianFactory(PaymentFactory):def create_payment(self):return YinlianPay()# client
pf = YinlianFactory()
pm = pf.create_payment()
pm.pay(300)
抽象工厂模式
- 定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
- 相比工厂方法模式,抽象工厂模式中每个具体的工厂都生产一套产品。
from abc import abstractmethod, ABCMeta# --- 抽象产品
class PhoneShell(metaclass=ABCMeta):@abstractmethoddef show_shell(self):passclass CPU(metaclass=ABCMeta):@abstractmethoddef show_cpu(self):passclass OS(metaclass=ABCMeta):@abstractmethoddef show_os(self):pass# ---- 抽象工厂
class Phone_Factory(metaclass=ABCMeta):@abstractmethoddef make_shell(self):pass@abstractmethoddef make_cpu(self):pass@abstractmethoddef make_os(self):pass# ---- 具体产品
class SmallShell(PhoneShell):def show_shell(self):print("普通手机小手机壳")class BigShell(PhoneShell):def show_shell(self):print("普通手机大手机壳")class AplShell(PhoneShell):def show_shell(self):print("苹果手机壳")class SnapDragonCPU(CPU):def show_cpu(self):print("骁龙CPU")class MediaTekCPU(CPU):def show_cpu(self):print("联发科CPU")class AplCPU(CPU):def show_cpu(self):print("苹果CPU")class AndrodOS(OS):def show_os(self):print("安卓系统")class AplOS(OS):def show_os(self):print("IOS")# ---- 具体工厂
class IPhoneFactory(Phone_Factory):def make_shell(self):return AplShell()def make_cpu(self):return AplCPU()def make_os(self):return AplOS()# ---- 客户端
class Phone:def __init__(self, cpu, os, shell):self.cpu = cpuself.os = osself.shell = shelldef 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)phone = make_phone(IPhoneFactory())
phone.show_info()
建造者模式
-
将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示
-
角色:
- 抽象建造者(Builder)
- 具体建造者(Concrete Builder)
- 指挥者(Director)
- 产品(Product)
-
建造者模式与抽象工厂模式相似,也用来创建复杂对象。
-
主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
from abc import ABCMeta, abstractmethodclass Player:def __init__(self, face=None, body=None, arm=None, leg=None):self.face = faceself.body = bodyself.arm = armself.leg = legdef __str__(self):return "%s, %s, %s, %s" %(self.face, self.body, self.arm, self.leg)class PlayerBuilder(metaclass=ABCMeta):@abstractmethoddef build_face(self):pass@abstractmethoddef build_body(self):pass@abstractmethoddef build_arm(self):pass@abstractmethoddef build_leg(self):passclass SexyGirlBuilder(PlayerBuilder):def __init__(self):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):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 build_player(self, builder):builder.build_body()builder.build_face()builder.build_arm()builder.build_leg()return builder.player# client
builder = MonsterBuilder()
director = PlayerDirector()
p = director.build_player(builder)
print(p)
单例模式
- 保证一个类只有一个实例,并提供一个访问他的全局访问点。
# 单例模式
class Singleton:def __new__(cls, *args, **kwargs):# cls代指类本身,self代指对象本身if not hasattr(cls, "_instance"):# 看这个类是否有这个属性cls._instance = super(Singleton, cls).__new__(cls)return cls._instanceclass Myclass(Singleton):def __init__(self, a):self.a = aa = Myclass(10)
print(a.a)
# 输出10
b = Myclass(20)
print(b.a)
print(a.a)
# 两次均输出20,因为没重写Singleton的__init__方法
print(id(a), id(b))