大话设计模式之桥接模式

 

    手机发展到今天,在残酷的竞争至下,你方唱罢我登场,原来的老大诺基亚、黑莓等厂商,现在已日薄西山,新兴的安卓(三星)、苹果手机早已将他们远远的抛在了身后。某日,突发奇想:造成今天的这个局面是不是也有“桥接模式”的一份功劳呢?

 

    想当年,不论是用的Nokia3210C还是7610,每次下载软件都得找符合自己手机型号和系统(S40S60V2S60V3等)的软件。如今,安卓系统的手机,只要符合系统(Android2.3Android4.0等)要求,不论型号,不论厂商,基本上都可以直接使用了。这样就大大方便了我们手机用户,为什么呢,且看下面结构设计的演化:

 

    假设:生产一个M品牌和一个N品牌的手机,它们都需要通讯录和游戏的功能。那么,此时我们可以按照品牌分类实现结构图:

    大话设计模式之桥接模式_第1张图片

    也可以按照软件分类实现结构图:

    大话设计模式之桥接模式_第2张图片

    如果现在手机需要增加一个MP3的功能,那么直接按照所分的类,添加分枝即可。如果再生产一个S品牌的手机,MP3、通讯录、游戏的功能都需要有,此时,上述两种分类方法的分枝将会非常臃肿!在这里我就不画出来了。这就是一直用继承造成的不良后果!事实上,很多情况用继承会带来麻烦,比如:对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现。子类的实现与它的负累有非常紧密的依赖关系,以至于父类视线中的任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更合适的类替换。这种依赖关系限制了灵活性并最终限制了复用性。其本质就是:继承是一种强耦合的结构,父类变,子类就必须要变。

    那么,我们可以换一种方式,采用如下形式的分类:

    大话设计模式之桥接模式_第3张图片

  

    同样的,增加一个MP3功能,再增加一个具有所有功能的S品牌手机,在这种模式下,只需要在“手机软件”类和“手机品牌”类上个增加一个分支即可。体系结构比上述的两种分类方法要精简很多,而且封装更加彻底。上述两种分类方法可以代表诺基亚手机和塞班系统,最后一种分类方法可以代表安卓手机和安卓系统。

 

    在这种分类方式中运用到了“合成/聚合复用原则”:尽量使用合成/聚合,尽量不要使用类继承。它的好处是:优先使用对象的合成/聚合将有助于我们保持每个类被封装,并被集中在单个任务上。这样的类和类继承层次会保持较小规模,并且不太可能增长成为不可控制的庞然大物。

 

    其实,这个分类方法就是桥接模式的思想精髓,下面一起来认识这神通广大的大仙:桥接模式

    桥接模式(Bridge:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

    通俗一点就是说:实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分类出来让它们独立变化,减少它们之间的耦合。就是上述三种分类方法中的第三种分法。

    其UML图:

    大话设计模式之桥接模式_第4张图片

    相关代码:

    Implementor类

    abstract class Implementor
    {
        public abstract void Operation(); 
    }

   

    ConcreteImplementorA和ConcreteImplementorB等派生类

    class ConcreteImplementorA :Implementor 
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现A的方法执行");
        }
    }
    class ConcreteImplementorB :Implementor 
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现B的方法执行");
        }
    }

   

    Abstraction类

    class Abstraction
    {
        protected Implementor implementor;

        public void SetImplementor(Implementor implementor)
        {
            this.implementor = implementor;
        }

        public virtual void Operation()
        {
            implementor.Operation();
        }
    }


    RefinedAbstraction类

    class RefinedAbstraction :Abstraction 
    {
        public override void Operation()
        {
            implementor.Operation();
        }
    }

 

    客户端实现

    class Program
    {
        static void Main(string[] args)
        {
            Abstraction ab = new RefinedAbstraction();

            ab.SetImplementor(new ConcreteImplementorA ());
            ab.Operation();

            ab.SetImplementor(new ConcreteImplementorB ());
            ab.Operation();

            Console.Read();
        }
    }

    通过这个例子我们可以了解到,类并不是越多越好,继承也并不是用的越多越好。当只用继承会造成大量的类增加,不能满足开放-封闭原则时,就应该考虑到用桥接模式了。

    大话设计模式敲到现在,很多时候我们并不值是在单纯的利用某个模式,而是更多的遵守设计过程中需要利用的五个设计原则:单一职责原则、开放封闭原则、依赖倒转原则、迪米特法则和合成/聚合复用原则。以后,等这些设计模式使用熟练了,也就不再会有模式之分,而只需遵循设计原则即可。

你可能感兴趣的:(大话设计模式之桥接模式)