Python设计模式-桥接模式
基于Python3.5.2,代码如下
#coding:utf-8
class Shape():
name = ""
param = ""
def __init__(self,*param):
pass
def getName(self):
return self.name
def getParam(self):
return self.name,self.param
class Pen():
shape = ""
type = ""
def __init__(self,shape):
self.shape = shape
def draw(self):
pass
class Rectangle(Shape):
def __init__(self,long,width):
self.name = "Rectangle"
self.param = "Long:%s Width:%s"%(long,width)
class Circle(Shape):
def __init__(self,radius):
self.name = "Circle"
self.param = "Radius :%s"%(radius)
class NormalPen(Pen):
def __init__(self,shape):
Pen.__init__(self,shape)
self.type = "Normal Line"
def draw(self):
print("draw ",self.type,self.shape.getName(),self.shape.getParam())
class BrushPen(Pen):
def __init__(self, shape):
Pen.__init__(self, shape)
self.type = "BrushPen Line"
def draw(self):
print("draw ", self.type, self.shape.getName(), self.shape.getParam())
if __name__ == "__main__":
rect = Rectangle("10","20")
cir = Circle("15")
n = NormalPen(rect)
n.draw()
n1 = NormalPen(cir)
n1.draw()
b = BrushPen(rect)
b.draw()
桥接模式分析与解读
桥接模式
将抽象部分与它的实现部分分离,使它们都可以独立变化。在桥接模式的基础是建立在合成/聚合复用原则(CARP),尽量使用合成/聚合。聚合表示一种弱的拥有关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;合成则是一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。例如,人的眼睛和人是部分和整体的关系,并且两者拥有同样的生命周期,所以就属于合成关系;一群皮皮虾里,每只皮皮虾都属于虾群,一个虾群拥有多只皮皮虾,所以皮皮虾对应虾群就是聚合关系。这里对类的继承进行说明,对象的继承关系是在编译时就定义好了,所以无法再运行时改变从父类继承的实现,子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然导致子类发生变化,当你需要复用子类时,如果继承下来的实现不合适解决新的问题,则父类必须重写或被其他更合适的类替换,这种依赖关系限制了灵活性并最终限制了复用性。在桥接模式下,就是将两个类进行聚合,使两个类分别实现,而不进行继承实现。
桥接模式的适用场景
1、不适用继承或者原继承关系中抽象类可能频繁变动的情况,可以将原类进行拆分,拆成实现花角色和抽象化角色;
2、重用性比较大的场景。比如开关控制逻辑的程序,开关就是抽象画角色,开关的形式有很多种,操作的实现化角色有很多种。
解读
代码中,分别定义了形状类(Shape)和画笔类(Pen),然后通过各自父类进行继承实现:
1、定义了Shape的子类Rectangle和Circle,分别定义相应参数;
2、定义了Pen的子类NormalPen和BrushPen,并在初始化的时候传入对应的Shape类,分别实现不同的draw()方法,来实现与Shpae类对象进行关联;
3、在客户端调用时,先生成对应的Shape类,然后将生成的Shape类在Pen类初始化的时候传入,再调用draw()方法,来实现不同形状的draw;
程序运行结果如下:
draw Normal Line Rectangle (‘Rectangle’, ‘Long:10 Width:20’)
draw Normal Line Circle (‘Circle’, ‘Radius :15’)
draw BrushPen Line Rectangle (‘Rectangle’, ‘Long:10 Width:20’)
通过运行结果,当传入不同的形状类型时,绘制了不同的形状,如果需要新增Shape类型,只需要继承Shape类,然后实现相应方法,符合对扩展开发,对修改封闭原则。
桥接模式的优缺点
优点:
1、抽象角色与实现角色相分离,二者可以独立设计,不受约束;
2、扩展性强:抽象角色和实现角色可以非常灵活地扩展。
缺点:
1、增加对系统理解的难度。
备注
# 接口实现类
class Implementor:
def Operation(self):
raise NotImplementedError
class ConcreteImplementorA(Implementor):
def Operation(self):
print("实现 A的方法")
class ConcreteImplementorB(Implementor):
def Operation(self):
print("实现 B的方法")
# 抽象类
class Abstraction():
def __init__(self,implementor):
self.implementor = implementor
def Operation(self):
raise NotImplementedError
class RefineAbstraction(Abstraction):
def Operation(self):
self.implementor.Operation()
if __name__ == "__main__":
a = ConcreteImplementorA()
b = ConcreteImplementorB()
aa = RefineAbstraction(a)
ab = RefineAbstraction(b)
aa.Operation()
ab.Operation()
该实现方法更适合不同语言的通用方法。