【python设计模式4】结构型模式1
目录
适配器模式
桥模式
适配器模式
将一个类的接口转换成客户希望的另外一个接口,适配器使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。实现适配器的两种方式,类适配器使用多继承,对象适配器使用组合
。组合就是一个类中放入另一类的对象。
先来看下组合:
class A:
pass
class B:
def __init__():
self.a = A()
类适配器模式使用示例:
# 类适配器模式使用示例:
from abc import ABCMeta, abstractmethod
# 目标接口
class Payment(object, metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def pay(self, money):
print('支付了%d' % money)
# 待适配的类
class BankPay():
def cost(self, money):
print('银联支付了%d' % money)
# 类适配器
class PaymentAdapter(Payment, BankPay):
"""
把不兼容cost转换成pay
"""
def pay(self, money):
self.cost(money)
p = PaymentAdapter()
p.pay(100)
"""
银联支付了100
"""
对象适配器模式使用示例:
# 类适配器模式使用示例:
from abc import ABCMeta, abstractmethod
# 目标接口
class Payment(object, metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass
class Alipay(Payment):
def pay(self, money):
print('支付了%d' % money)
# 待适配的类
class BankPay():
def cost(self, money):
print('银联支付了%d' % money)
# 待适配的类
class ApplePay():
def cost(self, money):
print('苹果支付了%d' % money)
# 对象适配器
class PaymentAdapter(Payment):
def __init__(self, payment):
self.payment = payment
def pay(self, money):
self.payment.cost(money)
p = PaymentAdapter(ApplePay())
p.pay(100)
p = PaymentAdapter(BankPay())
p.pay(100)
"""
苹果支付了100
银联支付了100
"""
适配器模式有三种角色,分别是目标接口、待适配的类和适配器。适用场景是:想使用一个已存在的类,而它的接口不符合你的要求。想使用一些已经存在的类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
桥模式
桥模式是将一个事物的两个维度分离,使其都可以独立地变化。当事物有两个维度的表现,两个维度都可能扩展时使用。优点是:抽象和实现相分离,扩展能力强。如果不使用桥模式,在任何维度进行扩展,需要改好多代码,因为使用到了继承:
class Shape:
pass
class Rectangle(Shape):
pass
class Circle(Shape):
pass
class RedRectangle(Rectangle):
pass
class GreenRectangle(Rectangle):
pass
class RedCircle(Circle):
pass
class GreenCircle(Circle):
pass
以上代码形状和颜色两个维度是通过类的继承关系紧密结合在一起,是紧耦合。紧耦合是是不可取的,应用桥模式的思想,可以使用组合来实现(松耦合)。如果需要画直线,直接加上直线的类。需要新颜色,直接加上颜色的类。两个维度都可以自由扩展,不需要添加很多代码。这里的角色有抽象、细化抽象、实现者和具体实现者:
from abc import ABCMeta, abstractmethod
# 抽象
class Shape(metaclass=ABCMeta):
def __init__(self, color):
self.color = color
@abstractmethod
def draw(self):
pass
# 实现
class Color(metaclass=ABCMeta):
@abstractmethod
def paint(self, shape):
pass
# 细化抽象
class Rectangle(Shape):
name = '长方形'
def draw(self):
self.color.paint(self)
# 如果要扩展形状,只需要添加形状类
class Circle(Shape):
name = '圆形'
def draw(self):
self.color.paint(self)
# 细化实现
class Red(Color):
def paint(self, shape):
print('画红色的%s' % shape.name)
# 如果要扩展颜色,只需要添加颜色类
class Green(Color):
def paint(self, shape):
print('画绿色的%s' % shape.name)
rectangle = Rectangle(Red())
rectangle.draw()
circle = Circle(Green())
circle.draw()
"""
画红色的长方形
画绿色的圆形
"""