设计模式
设计模式
接口:
-
一种特殊的类.声明了若干个方法,要求继承该接口的类必须实现这些方法.
-
作用:
限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现.
-
接口就是一种抽象类的基类(父类),限制继承它的类必须实现接口中定义的某些方法
-
-
python 中的接口实现
from abc import abstractmethod, ABCMeta class InterFace(metaclass=ABCMeta): @abstractmethod def method(self): pass def method1(self): raise NotImplementedError class Asd(InterFace): # 必须重写父类的 method 方法 pass Asd()
设计模式六大原则:
-
开闭原则
一个软件实体如类,模块和函数应该对扩展开放, 对修改关闭. 即软件实体尽量在不修改原有代码的情况下进行扩展
-
里氏 (Liskov) 替换原则
所有引用基类的地方必须能透明的 使用其子类的对象.
-
依赖倒置原则
高层模块不应该依赖底层模块,二者都应该依赖其抽象; 抽象不应该依赖细节;细节应该依赖抽象.
要针对接口编程, 而不是针对实现编程
-
接口隔离原则
使用多个专门的接口,而不是用其单一的总接口,即客户端不应该依赖那些它不需要的接口
-
迪米特法则
一然见实体应当尽可能少的与其他实体发生相互作用
-
单一职责原则
不要存在多于一个导致类变更的原因,
即一个类只负责一项职责
单例模式
- 保证一个类只有一个实例,并提供一个访问它的全局访问点
class Singleton(object):
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, name=None):
if name is not None:
self.name = name
a = MyClass("a")
b = MyClass("b")
c = MyClass("c")
print(a.name) # c
print(b.name) # c
print(c.name) # c
简单工厂模式
-
内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
-
角色:
工厂角色(Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
-
优点:
隐藏了对象创建的实现细节
客户端不需要修改代码
-
缺点:
违反了单一职责原则,将创建逻辑几种到一个工厂类里
当添加新产品时,需要修改工厂类代码,违反了开闭原则
# coding : utf-8
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def __init__(self, use_huabei):
self.use_huabei = use_huabei
def pay(self, money):
if self.use_huabei:
print("花呗支付%s元" % money)
else:
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元" % money)
class PaymentFactory:
def create_payment(self, method):
if method == "alipay":
return Alipay()
elif method == 'huabei':
return Alipay(use_huabei=True)
elif method == "applepay":
return ApplePay()
else:
raise NameError(method)
# 傻子程序员
pf = PaymentFactory()
p = pf.create_payment("huabei")
p.pay(100)
工厂方法模式
-
适用场景:
需要生产多种、大量复杂对象的时候
需要降低耦合度的时候
当系统中的产品种类需要经常扩展的时候
-
优点:
每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
隐藏了对象创建的实现细节
-
缺点:
每增加一个具体产品类,就必须增加一个相应的具体工厂类
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def __init__(self, use_huabei):
self.use_huabei = use_huabei
def pay(self, money):
if self.use_huabei:
print("花呗支付%s元" % money)
else:
print("支付宝支付%s元" % money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
class PaymentFactory(metaclass=ABCMeta):
@abstractmethod
def create_payment(self):
pass
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
class HuabeiFactory(PaymentFactory):
def create_payment(self):
return Alipay(use_huabei=True)
class ApplePayFactory(PaymentFactory):
def create_payment(self):
return ApplePay()
# 用户输入
# 支付宝,120
af = HuabeiFactory()
ali = af.create_payment()
ali.pay(120)
抽象工厂模式
-
内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
-
例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
-
角色:
n抽象工厂角色(Creator)
n具体工厂角色(Concrete Creator)
n抽象产品角色(Product)
n具体产品角色(Concrete Product)
n客户端(Client)
-
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
# coding : utf-8
# create by ztypl on 2017/5/25
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 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 = 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()
适配器模式
# coding : utf-8
# create by ztypl on 2017/5/25
from abc import abstractmethod, ABCMeta
# A
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%s元"%money)
class ApplePay(Payment):
def pay(self, money):
print("苹果支付%s元"%money)
#------待适配类------
# B
class WechatPay:
def huaqian(self, money):
print("微信支付%s元"%money)
class BankPay:
def huaqian(self, money):
print("银行卡支付%s元"%money)
# 适配器
# 类适配器
# class RealWechatPay(Payment, WechatPay):
# def pay(self, money):
# self.huaqian(money)
# 复用代码: 继承 组合
# class A:
# pass
#
# class C:
# pass
#
# class B:
# def __init__(self):
# self.a = A()
# self.c = C()
# 对象适配器
class PaymentAdapter(Payment):
def __init__(self, bad_payment):
self.p = bad_payment()
def pay(self, money):
self.p.huaqian(money)
p = PaymentAdapter(WechatPay)
p.pay(100)
代理模式
# coding : utf-8
# create by ztypl on 2017/5/26
from abc import ABCMeta, abstractmethod
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
@abstractmethod
def set_content(self):
pass
class RealSubject(Subject):
def __init__(self, filename):
print("读取%s文件内容"%filename)
f = open(filename)
self.content = f.read()
f.close()
def get_content(self):
return self.content
def set_content(self):
pass
# 虚代理
class ProxyB(Subject):
def __init__(self, filename):
self.filename = filename
self.subj = None
def get_content(self):
if not self.subj:
self.subj = RealSubject(self.filename)
return self.subj.get_content()
obj = ProxyB('abc.txt')
print(obj.get_content())
class ProxyC(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return self.subj.get_content()
def set_content(self):
raise PermissionError
责任链模式
观察者模式
策略模式
人工智能论坛
www.aboutyun.com