闲话-依赖倒置原则

依赖倒置原则


本质 :高层模块不因该直接依赖于底层模块的实现,而应该依赖于底层模块的抽象。即,模块类之间的依赖是基于抽象类的,实现类之间不能有直接的依赖关系,其依赖关系是通过接口或者抽象类产生的。另外,接口和抽象类不应该依赖于实现类,而实现类应该依赖于接口或者抽象类。也就是我们常说的:面向接口编程

上一节分享了开闭原则,这节我们再着重分析一下依赖倒置原则

故事情节: 还是砸金蛋活动,我们有锤子和斧子两个工具,顾客可以挑选使用其中之一来砸开金蛋获得奖励;在上一节开闭原则中(具体的故事情节看上节),根据开闭原则的原理实现了相应的逻辑代码,代码如下:

  • 定义工具的抽象接口
public interface IBaseTool {
        //敲击
        void Rap ();
    }

接口中定义一个方法,用来约束实现类实现敲击的功能

  • 定义具体的锤子工具,实现工具的抽象接口
//锤子工具
public class HammerTool : IBaseTool {
    private string toolName = "锤子";
    private int count = 3;
    //锤子需要敲击三次才能砸开金蛋
    public void Rap () {
        for (int i = 0; i < count; i++) {
            Console.WriteLine ("{0} : 第{1}次", toolName, i + 1);
        }
    }
}

需要使用锤子敲击三次才能砸开金蛋,获得奖品

  • 定义具体的斧子工具类,实现工具的抽象接口
//斧子工具
public class HatChetTool : IBaseTool {
    private string toolName = "斧子";
    private int count = 1;
    //斧子只需敲击一次就能砸开金蛋
    public void Rap () {
        Console.WriteLine ("{0} : 第{1}次",toolName,count);
    }
}

使用斧子,只需一次就能砸开金蛋

  • 顾客类
 //顾客
public class User {
    private IBaseTool _baseTool;
    public User (IBaseTool baseTool) {
        _baseTool = baseTool;
    }
    public void UserTool () {
        _baseTool.Rap ();
    }
}

这里可以看出,顾客类依赖于工具类的抽象接口,User 类属于我们的高层模块,符合高层模块不依赖于底层模块(HatChetTool和HammerTool),而依赖于底层模块的抽象(IBaseTool)。

依赖是可以相互传递的,比如对象A依赖于对象B,对象B又依赖于对象C,对象C又依赖于对象D,对象与对象之间存在诸多的依赖关系。需要做到对象之间的相互依赖是依赖于具体对象的抽象,而不是依赖于具体的对象。

通常,对象的依赖关系有三种方式来传递:

构造函数注入 ;比如我们之前的顾客类
//顾客
public class User {
    private IBaseTool _baseTool;
    public User (IBaseTool baseTool) {
        _baseTool = baseTool;
    }
    public void UserTool () {
        _baseTool.Rap ();
    }
}
通过Setter方法传递依赖对象
public class User_01 {
        private IBaseTool _baseTool;
        
        public void Setter (IBaseTool baseTool) {
            this._baseTool = baseTool;
        }
        public void UserTool () {
            _baseTool.Rap ();
        }
    }
通过接口声明依赖,定义工具的抽象接口
  public interface IBaseTools {
        void Rap (IUser user);
    }
  • 定义顾客类的抽象接口,在接口中传递对工具接口的依赖
public interface IUser {
        void UserTool (IBaseTool baseTool);
    }
  • 实现具体的用户类
public class User_02 : IUser {
    public void UserTool (IBaseTool baseTool) {
        baseTool.Rap ();
    }
}
  • 高层模块,客户端调用如下:
class Program {
        static void Main (string[] args) {
        
            IUser user_01 = new User_02 ();
            IBaseTool hammerTool = new HammerTool ();

            IUser user_02 = new User_02 ();
            IBaseTool HatChetTool = new HatChetTool ();

            user_01.UserTool (hammerTool);
            user_02.UserTool (HatChetTool);
        }
    }

可以看到,在高层模块中,User类和Tool类,均不依赖于具体的实现类user_01和user_02,hammerTool和HatChetTool ;而依赖于他们各自的抽象。

总结:

自己跟随文章的思路手打一遍(内容也不多),就总结出来了,自己总结的比楼主总结的好。

猜你喜欢

转载自blog.csdn.net/JianZuoGuang/article/details/89671259
今日推荐