依赖倒置原则,简称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;
/// <summary>
/// 汽车接口
/// </summary>
public interface ICar
{
/// <summary>
/// 是汽车就应该能跑
/// </summary>
void run();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Benz : ICar
{
/// <summary>
/// 奔驰车肯定会跑
/// </summary>
public void run()
{
Debug.Log("奔驰车开始运行......");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BMW : ICar {
/// <summary>
/// 宝马车肯定也会跑
/// </summary>
public void run()
{
Debug.Log("宝马车开始运行......");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 司机接口
/// </summary>
public interface IDriver {
/// <summary>
/// Setter方法注入
/// </summary>
/// <param name="car"></param>
void SetCar(ICar car);
/// <summary>
/// 是司机就应该会驾驶汽车
/// </summary>
/// <param name="car"></param>
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;
//}
/// <summary>
/// Setter方法注入
/// </summary>
/// <param name="car"></param>
public void SetCar(ICar car)
{
this.car = car;
}
/// <summary>
/// 司机的主要职责就是驾驶汽车
/// </summary>
/// <param name="car"></param>
public void driver()
{
car.run();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 场景实现类
/// </summary>
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 () {
}
}