建立型模式:工厂方法模式、抽象工厂模式、建立者模式、原型模式、单例模式。
python
不直接向客户端暴露对象建立的实现细节,而是经过一个工厂类来负责建立产品类的实例。该模式不属于23种设计模式之一。shell
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # abstract class @abstractmethod def pay(self, money): pass class Alipay(Payment): def __init__(self, use_huabei=False): self.use_huabei = use_huabei def 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: # 工厂类:生产支付对象 def create_payment(self, method): if method == 'alipay': return Alipay() elif method == 'wechat': return WechatPay() elif method == 'huabei': return Alipay(use_huabei=True) else: raise TypeError("No such payment named %s" % method) pf = PaymentFactory() # p = pf.create_payment('alipay') p = pf.create_payment('huabei') # 隐藏了类的内部实现,无需了解代码逻辑 p.pay(100)
Payment是抽象类,是为了让产品有一样的表现,能够一样的对外使用。若是要增长新的支付,好比银行支付,只要添加新的产品类便可。数据库
角色:设计模式
优势:微信
缺点:函数
定义一个用于建立对象的接口(工厂接口),让子类决定实例化哪个产品类。微信支付
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # 产品接口 # abstract class @abstractmethod def pay(self, money): pass class Alipay(Payment): # 具体产品 def __init__(self, use_huabei=False): self.use_huabei = use_huabei def 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 BankPay(Payment): # 建立一个新产品 def pay(self, money): print("银行卡支付%d元" % money) class PaymentFactory(metaclass=ABCMeta): # 工厂类接口 @abstractmethod def create_payment(self): pass class AlipayFactory(PaymentFactory): # 具体工厂类 def create_payment(self): return Alipay() class WechatPayFactory(PaymentFactory): def create_payment(self): return WechatPay() class HuabeiFactory(PaymentFactory): def create_payment(self): return Alipay(use_huabei=True) class BankPayFactory(PaymentFactory): # 建立新产品对应的工厂 def create_payment(self): return BankPay() pf = HuabeiFactory() # 建立工厂 p = pf.create_payment() p.pay(100)
角色:ui
优势:spa
缺点:操作系统
定义一个工厂类接口,让工厂子类来建立一系列相关或相互依赖的对象。
例:生产一部手机,须要手机壳、CPU、操做系统三类对象进行组装,其中每类对象都有不一样的种类。对每一个具体工厂,分别生产一部手机所须要的三个对象。
from abc import abstractmethod, ABCMeta # ------抽象产品------ class PhoneShell(metaclass=ABCMeta): # 手机壳 @abstractmethod def show_shell(self): pass class CPU(metaclass=ABCMeta): # cpu @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 SnapDragonCPU(CPU): def show_cpu(self): print("骁龙CPU") class MediaTekCPU(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_cpu(self): return SnapDragonCPU() def make_os(self): return Android() def make_shell(self): return BigShell() class HuaweiFactory(PhoneFactory): # 华为工厂 def make_cpu(self): return MediaTekCPU() def make_os(self): return Android() def make_shell(self): return SmallShell() class IPhoneFactory(PhoneFactory): # 苹果工厂,一套组件还作了限制 def make_cpu(self): return AppleCPU() # 苹果cpu def make_os(self): return IOS() # 苹果系统 def make_shell(self): return AppleShell() # 苹果手机壳 # ------客户端------ class Phone: # 手机 def __init__(self, cpu, os, shell): 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(IPhoneFactory()) # 生成一个苹果手机对象 p1.show_info()
相比工厂方法模式,抽象工厂模式中每一个具体工厂都生产一套产品。
角色:
优势:
缺点:
将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。
from abc import ABCMeta, abstractmethod class Player: # 产品:游戏角色 def __init__(self, face=None, body=None, arm=None, leg=None): # 传入初始化参数 self.face = face self.body = body self.arm = arm self.leg = leg def __str__(self): return "%s, %s, %s, %s" % (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): 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 Monster(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 = SexyGirlBuilder() # 建立一个性感女孩builder builder = Monster() # 建立一个怪物builder director = PlayerDirector() # 指挥者实例化 p = director.build_player(builder) # 组装建立(不一样角色建立函数都是相同的) print(p)
角色:
优势:
建造者模式与抽象工厂模式对比:
建造者模式与抽象工厂模式类似,也用来建立复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象(控制它的顺序),而抽象工厂模式着重于多个系列的产品对象。
保证一个类只有一个实例,并提供一个访问它的全局访问点。
from abc import abstractmethod, ABCMeta # 经过 __new__ 方法是实现单例模式的的一种方式,若是实例对象存在了就直接返回该实例便可,若是尚未,那么就先建立一个实例,再返回。 class Singleton: def __new__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): # 反射查看是否有_instance的类属性 cls._instance = super(Singleton, cls).__new__(cls) # 调用父类的__new__方法来建立实例 return cls._instance class MyClass(Singleton): def __init__(self, a): self.a = a a = MyClass(10) b = MyClass(20) print(a.a) # 输出20 print(b.a) # 输出20 print(id(a), id(b)) # 4400380840 4400380840, id相同说明二者是同一个实例 # 常应用于日志文件对象,数据库链接器对象,操做系统文件对象等状况使用。
角色:
优势:
抽象工厂模式和建造者模式相比于简单工厂模式和工厂方法模式而言更灵活也更复杂。
一般状况下、设计以简单工厂模式或工厂方法模式开发,当你发现设计须要更大的灵活性时,则向更复杂的设计模式演化。