python设计模式
对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计
面向对象三大特性:
- 封装 封装功能到类、私有__属性(双下划线开头)
- 继承 复用封装的代码
- 多态 python本身就是多态
接口:若干抽象方法的集合
作用:限制实现接口的类必须按照接口给定的调用方式实现这些方法;对高层模块隐藏了类的内部实现
python实现接口的两种方法:
方法一:抛出异常法raise NotImplementedError
,继承父类的子类必须实现父类的方法
class Payment:
def pay(self, money):
raise NotImplementedError
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%d元." % money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%d元." % money)
p = Alipay()
p.pay(100)
弊端:如果不去调用pay这个方法,依然不会抛出异常
方法二:继承ABCMeta,使用装饰器抽象方法abstractmethod
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
# abstract class ==》 ABC
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def pay(self, money):
print("支付宝支付%d元." % money)
class WechatPay(Payment):
def pay(self, money):
print("微信支付%d元." % money)
p = Wechatpay()
p.pay(100)
实现接口一般使用方法二
接口为底层代码,调用者为高层代码,方便高层代码直接查看接口拥有的功能,让团队协作效率更高
面向对象设计SOLID原则
开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
里氏替换原则:所有引用父类的地方必须能透明地使用其子类的对象。即,子类继承父类,子类重写父类的方法时,参数和返回值的类型必须相同,例如:
class User:
def show_name(self):
pass
class VIPUser(User):
def show_name(self):
pass
def show_user(u):
res = u.show_name() # 如果返回值User返回字符串,VIPUser返回图片,则导致数据无法处理
依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即高层模块不应该依赖那些它不需要的接口,例如:
class LandAnimal(metaclass=ABCMeta):
@abstractmethod
def walk(self):
pass
class WaterAnimal(metaclass=ABCMeta):
@abstractmethod
def swim(self):
pass
class SkyAnimal(metaclass=ABCMeta):
@abstractmethod
def fly(self):
pass
class Tiger(LandAnimal): # 只需要一个接口,需要把总接口进行细分
def walk(self):
print("老虎走路")
class Frog(LandAnimal, WaterAnimal): # 继承多个接口
pass
单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
设计模式分类
创建型模式(5种):工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式
结构型模式(7种):适配器模式、桥模式、组合模式、装饰模式、外观模式、享元模式、代理模式
行为型模式(11种):解释器模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式、模板方法模式