zoukankan      html  css  js  c++  java
  • 依赖倒置原则

    以为程序依赖于实现

    图一
    背景1:公司是福特和本田公司的金牌合作伙伴,现要求开发一套自动驾驶系统,只要汽车上安装该系统就可以实现无人驾驶,该系统可以在福特和本田车上使用,只要这两个品牌的汽车使用该系统就能实现自动驾驶。于是有人做出了分析如图一。
    对于图一分析:我们定义了一个AutoSystem类,一个FordCar类,一个HondaCar类。FordCar类和HondaCar类中各有三个方法:Run(启动Car)、Turn(转弯Car)、Stop(停止Car),当然了一个汽车肯定不止这些功能,这里只要能说明问题即可。AutoSystem类是一个自动驾驶系统,自动操纵这两辆车。

    代码实现

    编辑
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    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:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    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给我们提供了一种机制来实现这种“依赖倒置”。
    图二
    看图 2中这个简单的类图。这儿有一个“AutoSystem”类,它包含一个“ICar”接口。这个“AutoSystem”类根本不依赖于“FordCar”和“HondaCar”。所以,依赖关系被“倒置”了:“AutoSystem”模块依赖于抽象,那些具体的汽车操作也依赖于相同的抽象。
    于是可以添加ICar
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    public interface ICar
    {
    void Run();
    void Turn();
    void Stop();
    }
    public class BmwCar:ICar
    {
    public void Run()
    {
    Console.WriteLine("宝马开始启动了");
    }
    public void Turn()
    {
    Console.WriteLine("宝马开始转弯了");
    }
    public void Stop()
    {
    Console.WriteLine("宝马开始停车了");
    }
    }
    public class FordCar:ICar
    {
    publicvoidRun()
    {
    Console.WriteLine("福特开始启动了");
    }
    public void Turn()
    {
    Console.WriteLine("福特开始转弯了");
    }
    public void Stop()
    {
    Console.WriteLine("福特开始停车了");
    }
    }
    public class HondaCar:ICar
    {
    publicvoidRun()
    {
    Console.WriteLine("本田开始启动了");
    }
    public void Turn()
    {
    Console.WriteLine("本田开始转弯了");
    }
    public void Stop()
    {
    Console.WriteLine("本田开始停车了");
    }
    }
    public class AutoSystem
    {
    private ICar icar;
    public AutoSystem(ICar icar)
    {
    this.icar=icar;
    }
    private void RunCar()
    {
    icar.Run();
    }
    private void TurnCar()
    {
    icar.Turn();
    }
    private void StopCar()
    {
    icar.Stop();
    }
    }
    现在AutoSystem系统依赖于ICar 这个抽象,而与具体的实现细节HondaCar、FordCar、BmwCar无关,所以实现细节的变化不会影响AutoSystem。对于实现细节只要实现ICar 即可,即实现细节依赖于ICar 抽象。

    总结:

    A.高层次的模块不应该依赖于低层次的模块,他们(程序和实现)都应该依赖于抽象。

    B.抽象不应该依赖于具体,具体应该依赖于抽象。

    C.何谓倒置(个人理解)?正置:以往程序依赖于实现。倒置:实现依赖于程序【程序声明了抽象成员变量,而实现就是依赖抽象成员变量进行实现,间接就形成了实现依赖程序倒置关系】。

  • 相关阅读:
    EXT性能优化(转载)
    xampp 下配置mail()函数发邮件
    从存储过程中返回结果 (转载)
    HDU1394 Minimum Inversion Number
    HDU4414 Finding crosses
    POJ1328 Radar Installation
    HDU3308 LCIS
    POJ2352 Stars
    POJ2513 Colored Sticks
    HDU4027 Can you answer these queries?
  • 原文地址:https://www.cnblogs.com/chenweichu/p/5653873.html
Copyright © 2011-2022 走看看