DIP(依赖倒置原则)
高层模块不应该依赖于低层模块,两者都应该依赖抽象。
抽象即可理解为接口。
每次修改接口的时候,一定会修改对应的实现,但是修改实现的时候,很少需要修改对应的接口。也就是说,接口比实现稳定的多。所以说想要在架构上追求稳定,就必须多使用稳定的抽象接口,少依赖多变的实现。
依赖:
如果A类中使用了B类的实例,那么可以说A类依赖于B类。
比如:
如何在项目中使用数据库进行操作?
依赖关系如下:
这里高层模块即为业务处理,低层模块为MySQL类。
业务逻辑类使用了MySQL类,也就造成了业务类对MySQL类的依赖,如果这个时候要更换数据库,甚至更换数据存储的方式(文本等),那么业务类中的许多代码都要更改,这么写肯定是不合理的。
依赖方向控制:
既然上面的依赖方向不合理,应该让数据库类依赖业务类,也就是说对于业务类来说,不必关心用的是什么数据库,什么数据存储方式,而数据库类的设计要关心我们的业务类,针对业务类来设计。
也就是要让上面所说的依赖关系倒置过来。
那怎么让依赖关系倒置呢? 答案是使用接口
那么依赖关系就变成了:
同样地,如果换成Oracle,只需要实现IDatabase接口即可。
可以看到,两者都依赖于接口,对于数据库类(MySQL类)来说,依赖方向确实变了,虽然仅是依赖了接口,没有像上面说的依赖业务类,而且业务类也是依赖于接口类,依赖方向好像没有变。
对于业务类和MySQL类肯定是两个层次上的(一个高层,一个低层),或者说是属于两个模块的,那么这个接口类应该放在哪个模块里呢? 当然是业务类里,这也就是业务类针对接口编程,对>于负责业务类的人来说,仅需要针对这个接口编程,而不需要考虑数据库的细节(查询细节,表结构,数据库服务器问题,甚至数据库安装都挺麻烦的)。
如下 图,这个接口应该放在Business类所在的业务模块中。
这样以后更换数据库时,只需要更换MySQL对应的模块,并且针对接口类编写代码就好了,业务类几乎不用修改。这样业务类就摆脱了对某个数据库的依赖,而更关心业务的处理。
插件式架构:
上面的数据库就作为了业务处理的插件,可以选择更换插件。
同理,GUI也可以作为业务的一个插件,如果业务中出现了依赖GUI的类时,就可以像上面那样加一个接口,并把接口放在业务模块中实现依赖反转来控制依赖方向。那么以后就可以切换多种不>同类型的界面,如Web模式的界面,命令行模式的界面等, 同样不会影响业务处理模块。