依赖倒置原则

  What

  Dependence Inversion Principle(DIP):高层模块不应该依赖底层模块,都应该依赖于抽象;抽象不应该依赖于具体,具体依赖于抽象

  Why

  若高层依赖于底层,那么底层的变动也会导致高层的变动,这就会导致模块的复用性降低而且大大提高了开发的成本。若是依赖于抽象的话,那么是比较稳定的,底层或者高层的变动都不会互相影响。

  How

  很多地方引用的个人觉得也非常有代表性的一个例子:公司是福特和本田公司的金牌合作伙伴,现要求开发一套自动驾驶系统,只要汽车上安装该系统就可以实现无人驾驶,该系统可以在福特和本田车上使用,只要这两个品牌的汽车使用该系统就能实现自动驾驶。

  福特汽车类,包含三个方法,启动、停止、转弯

 class FordCar
    {
        public void Run()
        {
            Console.WriteLine("FordCar run");
        }

        public void Stop()
        {
            Console.WriteLine("FordCar stop");
        }

        public void Turn()
        {
            Console.WriteLine("FordCar turn");
        }
    }

  宏达汽车类,包含三个方法,启动、停止、转弯

  class HondaCar
    {
        public void Run()
        {
            Console.WriteLine("HondaCar run");
        }

        public void Stop()
        {
            Console.WriteLine("HondaCar stop");
        }

        public void Turn()
        {
            Console.WriteLine("HondaCar turn");
        }
    }

  自动驾驶系统,有三个方法启动汽车、停止汽车、汽车转向

  class AutoSystem
    {
        HondaCar hondaCar = new HondaCar();
        FordCar fordCar = new FordCar();
        CarType type;

        public AutoSystem(CarType type)
        {
            this.type = type;
        }

        public void RunCar()
        {
            if (type == CarType.Honda)
            {
                hondaCar.Run();
            }
            else if (type == CarType.Ford)
            {
                fordCar.Run();
            }
        }

        public void StopCar()
        {
            if (type == CarType.Honda)
            {
                hondaCar.Stop();
            }
            else if (type == CarType.Ford)
            {
                fordCar.Stop();
            }
        }

        public void TurnCar()
        {
            if (type == CarType.Honda)
            {
                hondaCar.Turn();
            }
            else if (type == CarType.Ford)
            {
                fordCar.Turn();
            }
        }
    }

  目前来看,是满足需求的,但是随着发展业务也在发展,现在如果发展了伙伴,需要对其他品牌的汽车添加自动驾驶系统,比如红旗、奇瑞等品牌,那么如果沿用以前的方式,就需要去修改AutoSystem了,先增加两个新的品牌汽车的对象,然后在启动汽车、停止汽车、汽车转向中进行修改增加分支语句对不同的品牌来进行判断然后加上各种操作,这样就违背的OCP,而且复杂的分支语句也会容易造成错误,如果以后再继续扩展其他的品牌的话,那么这样的程序肯定是不易于维护的,程序的健壮性是较差的,大大的增加了开发的成本。那么敏感的同学已经看出来,既然不同的汽车品牌之间都拥有相同的行为,那么为什么不定义一个接口呢?现在我们先来定义一个接口,然后将各个品牌的汽车实现这个接口实现,那么在AutoSystem中我们就可以针对定义的接口操作了。

    interface ICar
    {
        void Run();
        void Stop();
        void Turn();
    }

  自动驾驶系统也就是高层模块现在针对的是这个抽象的接口,无论什么汽车,只要实现了ICar接口,就能进行相关的操作。

    class AutoSystem
    {
        ICar car;

        public AutoSystem(ICar car)
        {
            this.car = car;
        }

        public void RunCar()
        {
            car.Run();
        }

        public void StopCar()
        {
            car.Stop();
        }

        public void TurnCar()
        {
            car.Turn();
        }
    }

  福特汽车类也就是底层模块,实现了ICar接口,现在依赖的是抽象的接口

    class FordCar : ICar
    {
        public void Run()
        {
            Console.WriteLine("FordCar run");
        }

        public void Stop()
        {
            Console.WriteLine("FordCar stop");
        }

        public void Turn()
        {
            Console.WriteLine("FordCar turn");
        }
    }

  宏达汽车类也就是底层模块,实现了ICar接口,现在依赖的是抽象的接口

    class HondaCar : ICar
    {
        public void Run()
        {
            Console.WriteLine("HondaCar run");
        }

        public void Stop()
        {
            Console.WriteLine("HondaCar stop");
        }

        public void Turn()
        {
            Console.WriteLine("HondaCar turn");
        }
    }

  当高层模块依赖底层的时候,那么高层的复用性就较差,就如上例所说的增加汽车品牌种类。如果高层与底层都是依赖于抽象的话,那么高层复用性就较好,因为通过继承象出来的接口实现多态,那么复用的地方就多了,这样的设计无疑是较为稳定的。

时间: 2024-10-25 14:45:11

依赖倒置原则的相关文章

设计模式六大原则: 老板是如何减轻负担的 -- 依赖倒置原则

很多创业公司都对外宣称"扁平化管理",什么是"扁平化管理"呢?请看下面这张架构图: 因为人少,老板直接管理着采购.销售.人力跟 IT 等人员,虽然累了点,但部门少.人不多也还好. 但是随着公司规模发展,每次新加入人员老板都要去认识.沟通,出现问题还得去约出去喝个茶,老板发现自己的时间都浪费在这些琐事,容易耽搁事不说,还发挥不出更大价值. 这时他决定招一些经理替自己分别管理各个部门,自己只要管理这些经理就好了. 于是新的架构图是这样的: 老板这下子省心多了,有问题直接

面向对象设计原则之四:依赖倒置原则

依赖倒置原则 所谓依赖倒置原则(Dependence Inversion Principle )就是要依赖于抽象,不要依赖于具体.简单的说就是对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合. 面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变化时,上层也要跟着变化,这就会导致模块的复用性降低而且大大提高了开发的成本. 面向对象的开发很好的解决了这个问题,一般的情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象.即使实现细节不断变化,只要抽象不变

设计原则之依赖倒置原则

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块, 负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修改类A,会给程序带来不必要的风险. 解决:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率. 举个栗子:讲一个读者读书的故事... 1. 新建一个类B

第2章 面向对象的设计原则(SOLID):3_依赖倒置原则

3. 依赖倒置原则(Dependence Inversion Principle,DIP) 3.1 定义 (1)要依赖抽象,不要依赖具体的实现类.简单的说就是对抽象(或接口)进行编程,不要依赖实现进行编程,这样就降低了客户与实现模块间的耦合.包含3层含义: ①高层模块不应依赖低层模块,两者都应该依赖于抽象 ②抽象不应该依赖细节 ③细节应该依赖于抽象 (2)何为“高层模块”和“低层模块” ①“低层模块”:每个逻辑的实现都是原子逻辑组成,不可分割的原子逻辑就是低层模块.一般和具体实现相关. ②“高层

设计模式之禅-依赖倒置原则

个人blog 此篇博文地址:http://www.sanyinchenblog.com/?p=167 依赖倒置原则(DIP): demo(https://github.com/sanyinchen/UMLDemo) 1.高层模块不应该依赖底层模块 2.抽象不应该依赖细节 3.模块间的依赖不是通过实现类发生的,而是由抽象类发生的 4.接口或者抽象类不依赖于细节 5.实现类依赖于接口或抽象类 书中给出的demo是Driver(司机)开Car(车)的场景. 从uml图中我们可以很清楚的看到ICar和I

对依赖倒置原则(DIP)及Ioc、DI、Ioc容器的一些理解

.概述 所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合,并由此引申出IoC.DI以及Ioc容器等概念. 2.意图 面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变动时上层也要跟着变动,这就会导致模块的复用性降低而且大大提高了开发的成本. 面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节

设计模式六大原则(3)--依赖倒置原则

定义: 高层次的模块不应该依赖于低层次的模块,两者都应该依赖于抽象接口:抽象接口不应该依赖于具体实现.而具体实现则应该依赖于抽象接口.依赖倒置原则英文全称为Dependence Inversion Principle,简称为DIP. 问题由来: 类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块,负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修改类A,会给程序带来不必要的风险. 解决方案: 将类A修改为依赖接口I,类B和

面向对象设计原则四:依赖倒置原则

依赖倒置原则(DIP)        定义:高层模块不应该依赖底层模块,两者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 好处:稳定性.可维护性.可扩展性. 概述:DI就是依赖倒置的意思,也可称为控制反转,我们以前编写结构化的程序当中,也就是C语言这样的语言时,高层模块依赖于底层模块,也就是调用者和被调用者的关系,调用者要依赖于被调用者,被调用者编写的一些功能和服务,会影响高层,一旦底层发生了变化,也就是被调用者发生了变化,就直接影响了高层也就是调用者.这样的设计,很难保证他的稳定性

Java设计原则—依赖倒置原则(转)

依赖倒置原则(Dependence Inversion Principle,DIP)的原始定义: 高层模块不应该依赖底层模块,两者都应该依赖其抽象: 抽象不应该依赖细节: 细节应该依赖抽象. 依赖倒置原则在Java语言中的表现是: 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的: 接口或抽象类不依赖于实现类: 实现类依赖接口或抽象类. 依赖倒置原则实际上就是要求"面向接口编程". 采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降

设计模式六大原则(3):依赖倒置原则

依赖倒置原则 定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块,负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修改类A,会给程序带来不必要的风险. 解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率. 依赖倒转原则(Dependency