转眼间,设计模式已经学了这么多了.
我觉得,设计模式其实就是如何抽象的更合理,如何让使用和实现分离.这些做法让我们的软件更容易的应对变化,如此而已.
前几天学的桥接模式.
当变化面向两个或以上的维度时,我们采用组合抽象的方法来应对变化。
什么组合抽象呢?让我们来看看桥接模式,你就知道了。
当一个对象,它可能发生两种变化:A维度和B维度。那么,我们就把A抽象出来叫做AbstractA,把B抽象出来叫做AbstractB。把它们组合起来,简单说就是把AbstractB的一个实例放在AbstractA中。B变化是辅助的抽象,主逻辑再A中。独立实现B的抽象以便以后使用 。在实现了AbstractA的具体实例中,我们就可以使用抽象B,而不去关心抽象B是怎么实现的。只需要传进去一个抽象B的具体实现实例就行了。在抽象A中,我们可以任意组合这两个维度,这就解决了一个对象两个维度剧烈变化的问题,就算它们纵横交错我们也不怕。
桥接模式的关键点和重点在与面向对象设计的原则:Prefer组合To继承。实际上使用多继承也是可以解决这些问题,但是并不是我们推荐的,这种多继承往往违背单一职责原则。而且,C#不支持多继承,所以必须继承两个接口。那么,抽象A和抽象B就使平等的关系,而抽象B不是主要的,它本身也许并没有什么独立的意义,这样就搞混了类之间的关系。
那么之前我学习了适配器模式,同样作为结构型模式,适配器模式更多的用在匹配原有接口,以适应新的变化要求.对于用户来说,原有的接口是黑盒的,不可见的.
而桥接模式更多的用在两条线的变化需求上.在设计的初期,应对主逻辑和辅逻辑的变化,我们就用桥接模式,把辅逻辑接口组合到主逻辑接口中,然后让他们分别去实现.
而在设计完成以后或者开发已经结束,发现现有的接口不能满足需求,那么我们就使用适配器模式,创建新的接口适配原接口以满足需求.
经过学习和实践,我们也可以了解到,这两个模式(bridge and adaptor)也经常一起使用.比如如下这个场景:桥接模式中的辅逻辑的某个实现需要使用某个外部接口,那么此时就可以把那个外部接口适配到这个实现中来,如此便同时使用了bridge和adaptor.说的有点儿抽象,不知道大家能不能理解,因为我没有找到太好的关于这方面的例子,如果哪位同志有,请千万拿出来和大家分享.
今天学的组合模式,觉得简单得没法再简单了.
但是,听说这可是使用的非常多的,特别有用的一个模式.所以各位也不要看轻了.组合模式,从名字就可以看出来,是把某种东西组合起来了.
那么为什么要组合起来呢?
就是为了更方便的调用.调用方(客户端)不管你是组合起来的还是单个的,统统都调用一个接口的方法.而Container(容器)包含了单个的SingleObject,不管是Container还是SingleObject都实现同一个接口,客户端只需要调用这个接口就可以了.在Container中,循环调用SingleObject以及它的方法,这样,接口同一,方便了客户端调用,简化了客户端代码,此时客户端已经不需要知道你是个Container 还是个SingleObject,反正都一样的接口.
一个公司的下面的所有的部门就是一个很好的例子.
总经理说:我要知道这个月的各个部门的工作.那么每个部门都应该呈交到秘书处一个报表,然后秘书汇总后交给总经理.
那么,如果我们没有使用组合模式,意思就是需要总经理一个一个部门的去问:你们部门这个月怎么样啊?会把他累死.
使用了组合模式,总经理就是个Client,它不需要关心各部门的报告(SingleObject)是怎么组合的,只看秘书处(接口)的汇总的东西就可以了.秘书处汇总在一起的报告(Container容器),直接交给总经理看.
例子举的又不合适的地方,还请各位务必指出,以便大家共同学习.初学者发表的东西有很多地方并不一定是对的,但是希望能给大家一些启发,让我们共同思考,完成软件设计开发大业,谢谢.:)