导言
在实际生活中,某些事物由于自身的逻辑,具有两个或多个维度的变化。例如,国家武装力量分为海军、陆军、空军三个军种,海、陆、空三军各自又有军、师、旅、团、营等建制。对于各个军种,以上的建制单位所包含的人数是不一样的。陆军人数较多、空军人数较少。这样,就产生了两个维度,一个是军种维度,另一个是具体的各个军种的建制维度。在军种维度,可以增加例如“外空”的新军种;在建制维度,可以修改在各个军种中的人数,或者增加一个新的军事单位。
相应的,在软件设计中,如何应对这种“多维度的变化”?如何巧妙的设计软件,使得系统可以沿着两个或者多个维度进行独立的增加或者变化,而这种变化又不会对现有的类产生影响呢?这种情况可以使用桥接模式(Bridge Pattern),其意图是将一个软件的抽象部分与实现部分分离,使它们都可以独立的变化。
当一种抽象有几种不同实现方法的时候,一个有效的方法是使用面向对象的继承概念,将其设计为一个层次类,通常是使用抽象类代表抽象部分,而由其他具体的类继承该抽象类,以便用不同的方法实现抽象超类所声明的功能。但是这种方法并不永远是唯一正确的选择,有时这种设计会影响其扩展性,尤其是当该层次类包含两个维度的变化时更是如此。
桥接模式是指将抽象部分与它的实现部分分离。使它们可以独立地变化。桥接模式的设计类图如图所示。
桥接模式的各组成部分即含义说明如下。
当要避免抽象部分和实现部分的永久绑定,例如实现部分必须在运行时被选择的时候,使用桥接模式。
需要注意的是,抽象部分和实现部分都应该被子类继承。这样,桥接模式可以使用户结合不同的抽象对象与实现对象,并且独立地扩展抽象部分与实现部分。甚至 Abstraction 的具体实现类 RefinedAbstraction 改变了,客户程序都不必重新编译。
桥接模式有如下优点。
桥接模式强调对象有两个以上维度的变化,简化多级继承关系,但同时增加了聚合对象的内部方法,因为它不得不多写方法以便包含它的类调用。
from abc import ABC, abstractmethod
class Abstraction(ABC):
def __init__(self, implementor):
self.implementor = implementor
@abstractmethod
def operation(self):
pass
class RefinedAbstractionA(Abstraction):
def operation(self):
print('RefinedAbstractionA')
self.implementor.operation_imp()
class RefinedAbstractionB(Abstraction):
def operation(self):
print('RefinedAbstractionB')
self.implementor.operation_imp()
class Implementor(ABC):
@abstractmethod
def operation_imp(self):
pass
class ConcreteImplementorA(Implementor):
def operation_imp(self):
print('ConcreteImplementorA')
class ConcreteImplementorB(Implementor):
def operation_imp(self):
print('ConcreteImplementorB')
class Client:
@staticmethod
def main():
concrete = input('concrete:')
abstract = input('abstract:')
implementor = eval(f'ConcreteImplementor{concrete}()')
implementor.operation_imp()
abstraction = eval(f'RefinedAbstraction{abstract}(implementor)')
abstraction.operation()
if __name__ == '__main__':
Client.main()
本文分享自 Python机器学习算法说书人 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!