依赖倒置原则
一:依赖倒置原则的由来
依赖倒置原则(Dependence Inversion Principle,DIP)
二:依赖倒置原则的定义
High level modules should not depend upon low level modules.Both should depend upon abstractions. Abstractions should not depend upon details.Details should depend upon abstractions.(高层模块不应该依赖低层模块,两者都应该依赖抽象,抽象不应该依赖细节,细节应该依赖抽象)
抽象:抽象类或者接口,两者都不能被实例化
细节:即具体的实现类,实现接口或继承抽象类所产生的类,两者都可以通过关键字new直接被实例化
三:依赖倒置原则的例子
//司机接口 public interface IDriver { void drive(ICar car); } //司机类的实现 public class Drive:IDriver { //构造函数注入 //private ICar car; //public Drive(ICar _car) //{ // this.car = _car; //} //Setter依赖注入 private ICar car; public void setCar(ICar _car) { this.car = _car; } public void drive(ICar car) { car.run(); } } //汽车接口 public interface ICar { void run(); } //汽车类的实现 public class Benz:ICar { public void run() { Console.WriteLine("奔驰车开始运行。。。"); } } //汽车接口以及两个类的实现 public class BMW : ICar { public void run() { Console.WriteLine("宝马车开始运行。。。"); } } //业务场景 class Program { static void Main(string[] args) { IDriver cjn = new Drive(); ICar ben = new Benz(); ICar bmw=new BMW(); cjn.drive(ben); cjn.drive(bmw); Console.Read(); } }
Client属于高层业务,他对低层模块的依赖都建立在抽象上,cjn的表面类型是IDriver,Benz的表面类型是ICar,在其后的操作者cjn都是以IDriver类型进行操作,这里也是里氏替换原则的体现
四:依赖的三种写法
1.构造函数传递依赖对象
public interface IDriver { void drive(ICar car); } //构造函数注入 public class Drive:IDriver { private ICar car; public Drive(ICar _car) { this.car = _car; } public void drive(ICar car) { car.run(); } }
2.Setter方法传递依赖对象
public interface IDriver { void drive(ICar car); } public class Drive:IDriver { private ICar car; public void setCar(ICar _car) { this.car = _car; } public void drive(ICar car) { car.run(); } }
1.接口声明依赖对象
在接口的方法中声明依赖对象
五:我的理解
面向接口编程,每个类尽量从接口或者抽象类中派生,把公共部分提取到接口或者抽象类中去,在结合里氏替换原则就能实现依赖倒置
参考书籍 设计模式之禅
评论