依赖倒置原则,简称DIP
定义:1.高层模块不应该依赖底层模块;2.抽象不应该依赖细节;3.细节应该依赖抽象;(针对接口 编程,不应该针对实现编程)
释义:1.高层模块与低层模块之间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依 赖关系是通过接口或抽象类产生的;
2.接口类和抽象类不依赖于实现类;
3.实现类依赖接口或抽象类;
依赖的三种写法
1.构造函数传递依赖对象;(见Driver脚本)
2.Setter方法传递依赖对象;(见Driver脚本)
3.接口声明依赖对象;(见IDriver脚本)
依赖是可以传递的,A对象依赖B对象,B又依赖C,C又依赖D,生生不息,依赖不止
只要做到抽象依赖,即使是多层的依赖传递也无所畏惧
依赖倒置遵循规则:
1.每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备(这是依赖倒置的基本要求,接口和抽象类都是属于抽象的,有了抽象才可能抽象倒置)
2.变量的表面类型尽量是接口或者抽象类
3.任何类都不应该从具体类派生
4.尽量不要覆写基类的方法(如果基类是一个抽象类,而且这个方法已经实现了,子类尽量不要覆写。类间依赖的是抽象,覆写了抽象方法,对依赖的稳定性会产生一定的影响)
5.结合里氏替换原则使用(接口负责定义public属性和方法,并声明与其它对象的依赖关系,抽象类负责公共构造部分的是实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化)
代码案例:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- ///
- /// 汽车接口
- ///
- public interface ICar
- {
- ///
- /// 是汽车就应该能跑
- ///
- void run();
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Benz : ICar
- {
- ///
- /// 奔驰车肯定会跑
- ///
- public void run()
- {
- Debug.Log("奔驰车开始运行......");
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class BMW : ICar {
- ///
- /// 宝马车肯定也会跑
- ///
- public void run()
- {
- Debug.Log("宝马车开始运行......");
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- ///
- /// 司机接口
- ///
- public interface IDriver {
- ///
- /// Setter方法注入
- ///
- ///
- void SetCar(ICar car);
- ///
- /// 是司机就应该会驾驶汽车
- ///
- ///
- void driver();
-
- ///接口声明依赖对象
- //void driver(ICar car);
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Driver : IDriver {
-
- private ICar car;
- 构造函数注入
- //public Driver(ICar _car)
- //{
- // this.car = _car;
- //}
-
- ///
- /// Setter方法注入
- ///
- ///
- public void SetCar(ICar car)
- {
- this.car = car;
- }
- ///
- /// 司机的主要职责就是驾驶汽车
- ///
- ///
- public void driver()
- {
- car.run();
- }
-
-
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- ///
- /// 场景实现类
- ///
- public class Client03 : MonoBehaviour {
-
- // Use this for initialization
- void Start () {
- //张三开奔驰车
- IDriver zhangsan = new Driver();
- ICar benz = new Benz();
- zhangsan.SetCar(benz);
- zhangsan.driver();
-
- //张三开宝马车
- ICar bmw = new BMW();
- zhangsan.SetCar(bmw);
- zhangsan.driver();
- }
-
- // Update is called once per frame
- void Update () {
-
- }
- }