桥接模式

在面向对象的编程中,我们经常会使用继承,但事实上,很多情况用继承会带来麻烦,因为对象的继承关系是在编译时就定义好了,所以无法再运行时改变从父类继承的实现,子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

因此,我们应该尽量使用合成/聚合,尽量不要使用类的继承。聚合表示一种弱的“拥有”关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;合成则是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。有限使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并被不太可能增长为不可控制的庞然大物。

在众多设计模式中,桥接模式是对合成/聚合的典型应用,假如实现系统可能有多个角度分类,每一种分类都有可能发生变化,那么就把这多种角度分离出来,让他们独立变化,减少它们之间的耦合。

例如,手机既有多个品牌,又有多种软件,就可以使用桥接模式实现,首先实现多种软件类:

   abstract class HandsetSoft
    {
        public abstract void Run();
    }

    class HandsetGame : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("Run Handset Game.");
        }
    }

    class HandsetAddressList : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("Run Handset Address List.");
        }
    }

下面实现多个手机品牌,在品牌类中使用聚合,引入不同的手机软件类:

    abstract class HandsetBrand
    {
        protected HandsetSoft soft;
        
        //设置当前需要使用的软件
        public void SetHandsetSoft(HandsetSoft soft)
        {
            this.soft = soft;
        }

        abstract public void Run();
       
    }

    class HandsetABrand : HandsetBrand
    {

        public override void Run()
        {
            Console.WriteLine("HandsetA Run:");
            soft.Run();
        }
    }

    class HandsetBBrand : HandsetBrand
    {
        public override void Run()
        {
            Console.WriteLine("HandsetB Run:");
            soft.Run();
        }
    }

客户端调用代码如下:

            HandsetABrand brandA = new HandsetABrand();
            brandA.SetHandsetSoft(new HandsetGame());
            brandA.Run();

            HandsetBBrand brandB = new HandsetBBrand();
            brandB.SetHandsetSoft(new HandsetAddressList());
            brandB.Run();

运行结果如下:

HandsetA Run:
Run Handset Game.
HandsetB Run:
Run Handset Address List.

在仅使用继承时,结构图如下,如果需要增加一个软件或一个手机品牌,都至少需要增加两个类,桥接模式巧妙地使用聚合关系替代了类的继承,这样,无论增加手机软件或是手机品牌,都只需要增加一个类既可。

posted @ 2016-05-09 09:34  angela217  阅读(202)  评论(0编辑  收藏  举报