顾名思义,桥的作用就是将两条相互独立的路桥接到一起,而两条路可以保持各自的相对独立。在程序设计中,“桥”模式中的桥只是一种形象的比喻。根据桥模式的定义,桥模式实现了一个主题(可以是一个类,也可以是一中设计上的概念)的抽象部分和实现部分的分离(有的地方定义为抽象与具体行为的分离)。抽象部分的基类和实现部分的基类充就当着桥(接口对接)的作用,而抽象部分的子类和实现部分的子类就是桥两边的路,可以各自相对独立的发展(变化)(之所以是相对独立,从实现上来讲就是这种变化不能脱离最终能够实现桥接这个目标)。
我们知道,对于对象的研究,我们可以用这样的模型来表达对象:属性和行为。行为和属性都是对象的特征,其中属性描述对象的静态特征,而行为表达对象的动态特征,一般来讲,动态特征往往跟静态特征密切相关,相互影响,静态特征会约束动态特征的(行为),比如一个人如果是小孩(属性),那么他的行为很多都是受约束的,反过来,如果一个人经过吃(行为),又会长大,影响到身高,体重等(属性)。因为对象的特征都会发生变化,如果我们要表达这种变化,一是需要对这些对象根据我们的实际需要进行抽象,提取需要的特征,而对那些次要或者不需要的特征进行剔除。但这仅仅是研究对象的基础--抽象,我们还是需要表达重要特征的变化。
对于静态特征而言,变化的表达比较简单,只需要修改特征值即可,而且在实现上也比较容易,只要不同层次的对象都保持自己的特征值即可。但对于行为特征就不一样了,因为行为特征不仅受到静态特征这个约束,还会受到环境的影响。要用分类模式来表达所有静态特征和行为特征的变化是很困难的,我们只考察一种静态特征和一种行为特征的变化,这是最基本的一种情况,考虑到现有的技术体系,我们有两种方法来实现:
A)利用类的单继承来实现(形成分类层次),比如人是抽象类,有个重要的特征性别,一个重要的行为跑,性别不同跑的行为当然也不一样,利用继承,我们可以派生出两个子类——男人和女人。这样行为跑也可以分为男人的跑和女人的跑,当然,如果仅仅是研究跑与性别的关系,问题是可以解决。但前面说了,行为除了受到静态特征的约束外,还会受到环境的影响,比如在不同产地的跑。这种情况下,如果还按照继承分类的方式去做,显然是不可取的,一是类体系太复杂,二是用环境来分类对象显然也不是一种可取的方式,因为环境是外在的。
B)通过类的多继承来实现,对于多个特征的变化,这种方法可以减少类的数量,对于上述的例子,我们可以用一个对象的抽象和环境(比如产地)的抽象,人可以分为男人,女人,环境可以分为沙地,塑料跑道等。要描述男人在沙地跑,我们就从沙地和男人继承形成一个新的子类。这种方式看起来是可以,但有很多问题,一是不太符合对象分类原则(研究对象的分类一般都是根据对象本身,而不是会根据环境),在类体系上对象与环境天然就应该分离。二是从技术实现上来讲也比较麻烦,也违背了责任单一原则。
那怎么来解决这种问题呢?我们来分析一下类的静态特征和动态特征,我们发现,对于静态特征的变化我们大多时候并不需要提供派生类来实现,只需要通过修改设置静态特征数据就可以了,只有那些对行为影响非常大,又属于我们主要研究范畴的静态特征,我们才需要按此属性进行派生,(比如,性别),而行为特征的变化,除了受到静态特征的影响外,还受到外界环境的影响,同时也会影响外界环境,比如人的跑这个行为在不同场地上跑是不一样的(比如沙地,水泥地),如果我们也采用继承的方式来实现这种变化,一是上面说的弊端,二从逻辑上我们也很难接受根据行为的环境来进行类派生的做法(虽然技术上是可以的),很难将一个跑在沙地和跑在水泥地人视为不同的类(人),但我们可以将场地进行抽象,将人在某个产地跑的行为委托给产地来实现,我们在人这个类中保持一个对场地的引用,而在跑的方法中除了实现自己必要的逻辑外,可以调用场地中的跑来具体实现跑的行为。因为双方各自可以采用继承的方式实现自己的变化,我们就可以在实际使用时临时指派具体场地。这样既减少了类的数量,又使得逻辑更加简单和灵活。下面是一个简单的例子类图:
从上面的例子我们可以看出,增加一个人的子类,或者增加一个产地,原来的结构都不需要动,符合设计的开闭原则。
A、桥模式实现了类中行为抽象与行为实现的分离,同时可以实现类本身和行为实现的各自发展。理论上对于任何特征都可以通过这种委托来实现抽象与实现的分离,但我觉得不推荐这种泛滥的应用,对于主要受静态特征影响而变化的行为我们可以通过继承来实现这种变化,只对受外在环境影响比较大的行为特征才使用这种模式来实现。
B.对于桥模式中抽象类保持一个对实现类的引用并不是必要的,对于上述例子,完全可以在通过Run的参数化来完成这种组合,这样人与产地的关系就可以从关联关系弱化到简单依赖。
C.桥模式提供了一种减少类的方法,为类沿着多维特征各自变化的情况提供了一种解决方法。
后记:桥模式可以实现系统在多个维度上的独立变化,这本身就要求系统在这些维度上的变化能够独立,如果这些维度相互之间存在着关联或者依赖,就会使得体系中关系过于复杂,相互之间的通信太多,甚至不能实现,比如人的行为跑,呼吸,说话,这几种行为相互影响有联系,就很难使用桥模式来实现,而在这种情况下就需要用建立数学模型的方式来进行。
==========================================
以前写的,稍做修改。