zoukankan      html  css  js  c++  java
  • 桥接模式

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

    因此,我们应该尽量使用合成/聚合,尽量不要使用类的继承。聚合表示一种弱的“拥有”关系,体现的是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.

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

  • 相关阅读:
    前后端交互中出现的问题(五)
    前后端交互中出现的问题(四)
    前后端交互中出现的问题(三)
    生成ssh密码并且添加到git远程仓库
    快捷键
    阿里一面
    B树,B+树的插入删除操作
    乐观锁与悲观锁
    并发编程中的Callable,Future,FitureTask
    java并发包下的lock接口与syschronized关键字的区别
  • 原文地址:https://www.cnblogs.com/angela217/p/5472726.html
Copyright © 2011-2022 走看看