16种设计模式
1.简单工厂模式
内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂来负责创建产品类的实例
角色:
工厂角色(Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
优点:
1.隐藏了对象创建的实现细节
2.客户端不需要修改代码
缺点:
1.违反了单一职责原则,将创建逻辑几种到一个工厂类里
2.当添加新产品时,需要修改工厂类代码,违反了开闭原则
from abc import ABCMeta,abstractmethod#约束类
class Payment(metaclass=ABCMeta):@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("花呗支付%s元"%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)#client
pf=PaymentFactory()
p=pf.create_payment('huabei')
p.pay(100)
2.工厂方法模式
from abc import ABCMeta,abstractmethod#约束类
class Payment(metaclass=ABCMeta):@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("花呗支付%s元"%money)else:print("支付宝支付%d元"%money)class WechatPay(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)#client
pf=WechatFactory()
p=pf.create_payment()
p.pay(100)
优点:
每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
隐藏了对象创建的实现细节
缺点:
每增加一个具体产品类,就必须增加一个相应的具体工厂类,会增加很多代码,有点麻烦
3.抽象工厂模式
优点:
将客户端与类的具体实现相分离
每个工厂创建了一个完整的产品系列,使得易于交换产品系列
有利于产品的一致性(即产品之间的约束关系)
缺点:
难以支持新种类的(抽象)产品,比较复杂
from abc import ABCMeta,abstractmethod#------抽象产品------
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 PhoneFactory(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 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()def make_os(self):return IOS()def make_shell(self):return AppleShell()#-------客户端--------
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)#p1=make_phone(MiFactory())
#p1=make_phone(HuaweiFactory())
p1=make_phone(IPhoneFactory())
p1.show_info()
4.建造者模式
8.适配器模式
内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
两种实现方式:
类适配器:使用多继承
对象适配器:使用组合
14.观察者模式
适用场景:
当一个抽象模型有两方面,其中一个方面依赖于另一个方面,将这两者封装再独立对象中以使它们可以各自独立地改变和复用
当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变
当一个对象必须通知其它对象,而它又不能假定其它对象是谁,换言之,你不希望这些对象是紧密耦合的
from abc import ABCMeta,abstractmethod
#抽象订阅者
class Observer(metaclass=ABCMeta):@abstractmethoddef update(self,notice):pass#抽象发布者
class Notice:def __init__(self):self.observers=[]def attach(self,obs):self.observers.append(obs)def detach(self,obs):self.observers.remove(obs)def notify(self):#推送for obs in self.observers:obs.update(self)#具体发布者
class StaffNotice(Notice):def __init__(self,company_info=None):super().__init__()self.__company_info=company_info@propertydef company_info(self):return self.__company_info@company_info.setterdef company_info(self,info):self.__company_info=infoself.notify()class Staff(Observer):def __init__(self):self.company_info=Nonedef update(self,notice):self.company_info=notice.company_infonotice=StaffNotice("初始公司信息")
s1=Staff()
s2=Staff()
notice.attach(s1)
notice.attach(s2)
notice.company_info="公司今年业绩非常好,给大家发奖金!!"
print(s1.company_info)
print(s2.company_info)
notice.detach(s2)
notice.company_info="公司明天放假"
print(s1.company_info)
print(s2.company_info)
优点:
1.目标和观察者直接的抽象耦合最小
2.支持广播通信
15.策略模式
内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化
角色:
抽象策略
具体策略
上下文
优点:
1.定义了一系列可重用的算法和行为
2.消除了一些条件语句
3.可以提供相同行为的不同实现
缺点:
客户必须了解不同的策略