前言
abc标准库最大的作用是指引如何远离造轮子的怪圈。
python本身并没有抽象类,抽象函数。需要通过abc库提供。
abc和程序设计模式密切相关。程序设计模式参见blog文献。
抽象超类:接口模式
实现方式:在Python3.0中,定义class类使用一个关键字参数metaclass等于抽象超类ABCMeta,以及特殊的@装饰器语法实现,必须由子类重载的方法用assert或者raise NotImplementedError异常来指明子类必须重载。
固,当子类没有重载抽象方法时不能实例化的。
from abc import ABCMeta, abstractmethod
'''
接口:一种特殊类声明了若干方法,要求继承该接口的类必须实现这种方法。
作用:限制继承接口的类的方法的名称及调用方式,隐藏了类的内部实现。
接口类的实现主要为了接口化,归一化,统一化,就是每个类的方法都有固定的名称。
'''
# Payment支付接口:定义的一种特殊的类!
class Payment(metaclass=ABCMeta):
# 抽象产品角色
def pay(self, money):
raise NotImplementedError # 继承接口的类必须实现这个方法,否则报错!
class AliPay(Payment):
# 具体产品角色
def __init__(self, enable_yuebao=False):
self.enable_yuebao = enable_yuebao
def pay(self, money):
if self.enable_yuebao:
print(f"使用余额宝支付{money}元")
else:
print(f"使用支付宝支付{money}元")
class ApplePay(Payment):
# 具体产品角色
def pay(self, money):
print(f"使用苹果支付{money}元")
class WeChartPay(Payment):
# 具体产品角色
def pay(self, money):
print(f"使用微信支付{money}元")
class YinLianPay(Payment):
# 具体产品角色
def pay(self, money):
print(f"使用银联支付{money}元")
if __name__ == "__main__":
while True:
ali = AliPay()
apple = ApplePay()
wechart = WeChartPay()
ways = input("请输入支付方式:支付宝、微信 or 苹果:")
if ways == "支付宝":
ali.pay(10)
break
elif ways == "微信":
wechart.pay(20)
break
elif ways == "苹果":
apple.pay(15)
break
else:
NameError
以上为基本的接口模式!
抽象超类:工厂方法模式
"""
工厂方法模式:
定义:定义一个创建对象的接口(工厂接口),让子类决定实例化哪个接口
角色:抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色
适用场景:需要生产多种,大量复杂对象的时候,需要降低代码耦合度的时候,当系统中的产品类经常需要扩展的时候
优点:每个具体的产品都对应一个具体工厂,不需要修改工厂类的代码,工厂类可以不知道它所创建的具体的类,隐藏了对
象创建的实现细节
缺点:每增加一个具体的产品类,就必须增加一个相应的工厂类
"""
from abc import ABCMeta, abstractmethod
from first_design.interface_design import AliPay, ApplePay, WeChartPay, YinLianPay
# 抽象工厂+工厂方法模式
class PaymentFactoryAbs(metaclass=ABCMeta):
# 抽象工厂
def create_payment(self, method):
raise NotImplementedError
class PaymentFactory1(PaymentFactoryAbs):
# 工厂角色
def create_payment(self, method):
if method == 'alipay':
return AliPay()
elif method == 'yuebao':
return AliPay(True)
elif method == 'applepay':
return ApplePay()
elif method == 'weixin':
return WeChartPay()
else:
return NameError
class PaymentFactory2(PaymentFactoryAbs):
# 工厂角色
def create_payment(self, method):
if method == 'yinhang':
return YinLianPay()
else:
return NameError
if __name__ == "__main__":
payment = PaymentFactory1()
payment2 = PaymentFactory2()
pay1 = payment.create_payment('weixin').pay(5)
pay2 = payment.create_payment('alipay').pay(15)
pay3 = payment.create_payment('yuebao').pay(25)
pay4 = payment.create_payment('applepay').pay(35)
pay5 = payment2.create_payment('yinhang').pay(45)
总结
abc库的抽象超类和抽象方法,装饰器等影响程序设计模式。有规范软件编程的作用。