设计模式
- 设计模式:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 单例模式
设计模式:
简单工厂模式
- 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
- 角色:
- 工厂角色(creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
- 优点:
- 隐藏了对象创建的实现细节
- 客户端不需要修改代码
- 缺点:
- 违反了单一职责原则,将创建逻辑几种到一个工厂类里
- 当添加产品时,需要修改工厂代码,违反了开闭原则
代码示例:
from abc import ABCMeta, abstractmethod
class Payment(mataclass=ABCMeta):
@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元.' % monet)
else:
print('支付宝支付%d元.' % monet)
class WechatPay(Payment):
def pay(self, money):
print('微信支付%d元.' % monet)
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:
return TypeError('No such payment named %s' % method)
'''
pf = PaymentFactory()
p = pf.create_payment('huabei')
p.pay(100)
'''
工厂方法模式
- 内容: 定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪个产品类。
- 角色:
- 抽象工厂角色
- 具体工厂角色
- 抽象产品角色
- 具体产品角色
- 优点:
- 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
- 隐藏了对象创建的实现细节
- 缺点:
- 每增加一个具体产品类,就必须增加一个相应的具体工厂类
# 工厂接口
# 抽象工厂角色
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 Alipay()
class HuabeiFactory(PaymentFactory):
def create_payment(self):
return Alipay(use_huabei=True)
# client
pf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)
抽象工厂模式
- 内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
- 相比工厂方法模式,抽象工厂模式中的每一个具体工厂都生产一套产品。
- 角色:
- 抽象工厂角色
- 具体工厂角色
- 抽象产品角色
- 具体产品角色
- 客户端
- 优点:
- 将客户端与类的具体实现想分离
- 每个工厂创建了一个完整的产品系列,使得易于交换产系列
- 有利于产品的一致性(即产品之间的约束关系)
- 缺点:
- 难以支持新种类的抽象产品
单例模式
- 内容:保障一个类只有一个实例,并提供一个访问它的全局访问点。
- 角色:
- 单例
- 优点:
- 对唯一实例的受控访问
- 单例相当于全局变量,但防止了命名空间被污染。
例:
from abc import abstractmethod, ABCMeta
class Singleton:
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, a):
self.a = a
if __name__ == "__main__":
a = MyClass(10)
b = MyClass(20)
print(a.a)
print(b.a)
print(id(a),id(b))