依赖倒置原则(DIP)
Dependence Inversion Principle,简称:DIP。
高层模块不应该依赖低层模块,两者都应该依赖其抽象,不要依赖细节
问题由来:
高层模块类一般由多个底层模块类组成,例如 计算器类 由 计算方法类,打印类 组成。
当我们需要新增 计算方法类 的计算方式时 ,如果没有使用设计原则,都是直接修改这个类,在里面添加方法
这样也会导致 计算器类 也需要修改添加一个方法引用,假如 计算方法类 是由多个 计算类 集合起来的中层
假如我们需要修改 计算类 ,添加完新功能后 ,我们 还得去 计算方法类 里修改,然后再去 计算器类 修改添加新功能
这样就会导致修改量剧增...并且高层封装好的类会被全部拆开来修改, 如果这个时候,计算器类 被大量运用于项目里
那么这样的一次紧急的功能添加,修改量将会是个灾难。。。
假如全部修改完了后发生了功能冲突事件...那将会被自己气死。
解决方案:
高层模块 计算器类 通过抽象接口来调用 计算方法类 和 打印类 。
这样 高层模块的调用就仅仅依赖接口名字,而不会去依赖 底层类名字。
底层类只要继承 接口 就可以被切换使用
类似于 老板 招人做事 ,会先设立职位(接口),工人就是获得了这个 职位(继承接口),做属于这个职位的事情(实现方法)
当工人辞职,老板再招个 新工人安排职位(继承接口)即可
依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读
依赖倒置原则就是程序逻辑在传递参数或关联关系时,尽量引用高层次的抽象,不使用具体的类,即使用接口或抽象类来引用参数,声明变量以及处理方法返回值等。
代码例子:
在Start里声明出A类
通过类注入来改变高层类A的内部功能
以此达到不修改A类来修改内部功能的目的。
使得高层A类不会依赖底层类。
结果:
public class ceshi002 : MonoBehaviour
{
void Start()
{
A a = new A(); //实例化计算器
a.i1 = new B1(); //注入计算方式
a.i2 = new C1(); //注入显示方式
a.function(3, 2);//运行
//以下为新增功能替换测试
a.i1 = new B2();
a.i2 = new C2();
a.function(3, 2);
a.i1 = new B1();
a.i2 = new C2();
a.function(5, 2);
a.i1 = new B2();
a.i2 = new C1();
a.function(5, 2);
}
}
抽象接口定义:
public interface I1 //定义接口方法 计算
{
float Operation(float x1, float x2);
}
public interface I2 //定义接口方法 打印显示
{
void draw(float x1);
}
高层类使用功能
public class A //高层计算器类
{
public I1 i1; //抽象计算接口
public I2 i2; //抽象打印接口
public void function(float x1, float x2)
{
i2.draw(i1.Operation(x1, x2));//组合接口功能使用
}
}
实现基础功能
public class B1 : I1 //实现接口方法 加法
{
public float Operation(float x1, float x2)
{
return x1 + x2;
}
}
public class C1 : I2 //实现接口方法 打印1
{
public void draw(float x1)
{
Debug.Log("计算结果是:" + x1);
}
}
新增功能
public class B2 : I1 //实现接口方法 新增功能 减法
{
public float Operation(float x1, float x2)
{
return x1 - x2;
}
}
public class C2 : I2 //实现接口方法 新增功能 打印2
{
public void draw(float x1)
{
Debug.Log("显示结果为:" + x1);
}
}