zoukankan      html  css  js  c++  java
  • 高层次的模块不应该依赖于低层次的模块

    https://baike.baidu.com/item/依赖倒置原则

    图一
    背景1:公司是福特本田公司的金牌合作伙伴,现要求开发一套自动驾驶系统,只要汽车上安装该系统就可以实现无人驾驶,该系统可以在福特和本田车上使用,只要这两个品牌的汽车使用该系统就能实现自动驾驶。于是有人做出了分析如图一。
    对于图一分析:我们定义了一个AutoSystem类,一个FordCar类,一个HondaCar类。FordCar类和HondaCar类中各有三个方法:Run(启动Car)、Turn(转弯Car)、Stop(停止Car),当然了一个汽车肯定不止这些功能,这里只要能说明问题即可。AutoSystem类是一个自动驾驶系统,自动操纵这两辆车。
     
     
    public class HondaCar{
        public void Run(){
            Console.WriteLine("本田开始启动了");
        }
        public void Turn(){
            Console.WriteLine("本田开始转弯了");
        }
        public void Stop(){
            Console.WriteLine("本田开始停车了");
        }
    }
    public class FordCar{
        publicvoidRun(){
            Console.WriteLine("福特开始启动了");
        }
        publicvoidTurn(){
            Console.WriteLine("福特开始转弯了");
        }
        publicvoidStop(){
            Console.WriteLine("福特开始停车了");
        }
    }
    public class AutoSystem{
        public enum CarType{
            Ford,Honda
        };
        private HondaCar hcar=new HondaCar();
        private FordCar fcar=new FordCar();
        private CarType type;
        public AutoSystem(CarType type){
            this.type=type;
        }
        private void RunCar(){
            if(type==CarType.Ford){
                fcar.Run();
            } else {
                hcar.Run();
            }
        }
        private void TurnCar(){
            if(type==CarType.Ford){
                fcar.Turn();
            } else { 
                hcar.Turn();
            }
        }
        private void StopCar(){
            if(type==CarType.Ford){
                fcar.Stop();
                } else {
                    hcar.Stop();
                }
        }
    }
    

      

    代码分析:上面的程序确实能够实现针对Ford和Honda车的无人驾驶,但是软件是在不断变化的,软件的需求也在不断的变化。
    背景2:公司的业务做大了,同时成为了通用、三菱、大众的金牌合作伙伴,于是公司要求该自动驾驶系统也能够安装在这3种公司生产的汽车上。于是我们不得不变动AutoSystem:
     
    public class AutoSystem{
    public enum CarType{
    Ford,Honda,Bmw
    };
    HondaCar hcar=new HondaCar();
    FordCarf car=new FordCar();
    BmwCar bcar=new BmwCar();
    private CarType type;
    public AutoSystem(CarTypetype){
    this.type=type;
    }
    private void RunCar(){
    if(type==CarType.Ford){
    fcar.Run();
    }
    else if(type==CarType.Honda){
    hcar.Run();
    }
    else if(type==CarType.Bmw){
    bcar.Run();
    }
    }
    private void TurnCar(){
    if(type==CarType.Ford){
    fcar.Turn();
    }
    else if(type==CarType.Honda){
    hcar.Turn();
    }
    else if(type==CarType.Bmw){
    bcar.Turn();
    }
    }
    private void StopCar(){
    if(type==CarType.Ford){
    fcar.Stop();
    }
    else if(type==CarType.Honda){
    hcar.Stop();
    }
    else if(type==CarType.Bmw){
    bcar.Stop();
    }
    }
    }
    

      

    分析:这会给系统增加新的相互依赖。随着时间的推移,越来越多的车种必须加入到AutoSystem中,这个“AutoSystem”模块将会被if/else语句弄得很乱,而且依赖于很多的低层模块,只要低层模块发生变动,AutoSystem就必须跟着变动,
    它最终将变得僵化、脆弱。
    导致上面所述问题的一个原因是,含有高层策略的模块,如AutoSystem模块,依赖于它所控制的低层的具体细节的模块(如HondaCar()和FordCar())。如果我们能够找到一种方法使AutoSystem模块独立于它所控制的具体细节,那么我们就可以自由地复用它了。我们就可以用这个模块来生成其它的程序,使得系统能够用在需要的汽车上。OOD给我们提供了一种机制来实现这种“依赖倒置”。
     
     

    https://zh.wikipedia.org/wiki/依赖反转原则

    应用依赖反转原则同样被认为是应用了适配器模式,例如:高层的类定义了它自己的适配器接口(高层类所依赖的抽象接口)。被适配的对象同样依赖于适配器接口的抽象(这是当然的,因为它实现了这个接口),同时它的实现则可以使用它自身所在低层模块的代码。通过这种方式,高层组件则不依赖于低层组件,因为它(高层组件)仅间接的通过调用适配器接口多态方法使用了低层组件,而这些多态方法则是由被适配对象以及它的低层模块所实现的。

    Dependency inversion principle - Wikipedia https://en.wikipedia.org/wiki/Dependency_inversion_principle

    In object-oriented design, the dependency inversion principle is a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. The principle states:[1]

    1. High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces).
    2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

    By dictating that both high-level and low-level objects must depend on the same abstraction, this design principle inverts the way some people may think about object-oriented programming.[2]

    The idea behind points A and B of this principle is that when designing the interaction between a high-level module and a low-level one, the interaction should be thought of as an abstract interaction between them. This not only has implications on the design of the high-level module, but also on the low-level one: the low-level one should be designed with the interaction in mind and it may be necessary to change its usage interface.

    In many cases, thinking about the interaction in itself as an abstract concept allows the coupling of the components to be reduced without introducing additional coding patterns, allowing only a lighter and less implementation-dependent interaction schema.

    When the discovered abstract interaction schema(s) between two modules is/are generic and generalization makes sense, this design principle also leads to the following dependency inversion coding pattern.

    Generalization restrictions[edit]

    The presence of interfaces to accomplish the Dependency Inversion Pattern (DIP) has other design implications in an object-oriented program:

    • All member variables in a class must be interfaces or abstracts.
    • All concrete class packages must connect only through interface or abstract class packages.
    • No class should derive from a concrete class.
    • No method should override an implemented method.[1]
    • All variable instantiation requires the implementation of a creational pattern such as the factory method or the factory pattern, or the use of a dependency-injection framework.
  • 相关阅读:
    常用Linux基础命令
    makefile基础
    获得当前的时间——system.currentTimeMillis()
    MapReduce提供的输入输出格式
    Hadoop HDFS文件操作的Java代码
    Hadoop2.2.0完全分布式配置
    Hadoop2.2.0伪分布模式配置
    Eclipse Plugin for Hadoop2.2.0
    Hadoop2.2.0单机模式配置
    Asp.Net 禁用cookie后使用session
  • 原文地址:https://www.cnblogs.com/rsapaper/p/9706904.html
Copyright © 2011-2022 走看看