依赖倒置原则
什么是依赖倒置
依赖倒置:Dependence Inversion Principle
我们先来看看Inversion的英文释义:
the action of inverting something or the state of being inverted.
(invert : put upside down or in the opposite position, order, or arrangement. )
如果有兴趣再搜索下Inversion图片多半会看到这样一张图片
在OOD中,依赖倒置指高层类的开发,不依赖低层类的实现细节,而是依赖于抽象接口。
当构建一个系统的时候,我们会在一些比较底层的类中实现一些基本的功能,比如记日志的类,操作数据库的类。在高级点的类中,去完成一些复杂逻辑(比如业务流程)。实现时,一种比较自然的做法就是,我们先写低层类,然后在高层类中调用底层的类完成复杂功能,也就是说高层依赖低层。但是这不算一种灵活的设计,比如如果低层的实现发生了改变时,高层不得不跟着变化修改。
举例说明
我们具体举例来说。我们有个数据库操作类DBExecutor,能够实现Create,Update,Delete三个方法,经数据更新到数据库。
接着我们在所有的应用层类中实现业务,将数据存储到数据库,处处都是new DBExecutor(),然后调用Create,Update,Delete的操作。比如
一开始我们的数据库使用的是SQL Server数据库,一切正常,突然有一天,领导决定我们要改用NoSQL型数据库存储。那我们首先会再实现一个NoSQLDBExecutor,这部分比较好处理,因为是一个新的类,没有地方引用。接着需要修改所有的之前调用DBExecutor的地方,改成通过NoSQLDBExecutor实例化db对象
我们不得不修改几乎所有的业务代码类,这个过程繁琐而又容易出错,也违反了封闭原则。
为了避免这样的问题,我们需要将关系依赖倒置,引入一个抽象接口,高层类在实现时依赖抽象接口,低层类也是基于这个抽象接口,这也就是依赖倒置,再实现功能的时候就是高层开始到低层
High Level Classes --> Abstraction Layer --> Low Level Classes
上面这个例子,我们先抽象一个接口
将来再更换为mysql数据库时,OrderAppService不需要任何改动。
实际操作(开发心得)
我们开发实操时,如果团队分为前台和后台开发,那应该由前台开发来定义我们的接口,而后台来实现接口。
我们的开发有可能是这样的:有个Controller层(高层),有个Service层(低层),Service层有实现,有接口,Controller层会去调用接口,而接口另有实现。
看起来似乎满足我们之前说的依赖倒置原则:高层(Controller)调用抽象(IService),而抽象的实现是Service。但是倒置的核心在于IService是由谁定义的,如果IService是由Service定义(比如先做实现,再抽取接口),那就依然是低层决定高层(Controller),如果IService是由Controller来定义的,才是真正意义上的依赖倒置。
比如我们实现注册功能,根据需求得到原型图如下:
点击【注册】按钮时,实现账号注册功能。
首先我们会先建一个RegisterController,新增一个接口Register
根据页面,我们设计Register方法的参数RegisterInput,需要两个手机号和验证码两个属性
新增接口IRegisterService,新增接口方法Register,参数RegisterInput
Controller引入接口IRegisterService,调用IRegisterService.Register
新增RegisterService实现IRegisterService
框架中的依赖倒置
什么是框架
框架及时用例实现某一类应用的结构性程序,是对某一类架构方案的可复用设计与实现。框架实现了多重设计模式,使得应用开发者不需要花太大力气,就能设计出结构良好的程序来。
即应用开发者,按照框架设计的规范创建或实现相关代码,框架自然会来调用这些代码,实现代码功能。
这其实就是依赖倒置,整个程序的运行是在框架中运行的(高层),而框架约定应用开发者的代码(低层)只要(而且必须要)按照约定的抽象接口实现代码,就能正常运行。
框架举例
比如.net的MVC开发框架,就是一套用于开发web站点应用程序的框架。
MVC即Model-View-Controller,Model(模型)组织数据。 View(视图)显示数据。 Controller(控制器)处理输入。
Controller必须放在Controllers文件夹下,命名必须为XXController,每个Controller里面有不同的Action处理不同的请求,会跳转到视图,这个视图在Views文件夹下,文件名同Action。
上面提到了不少必须,约定,这就是当我们在MVC框架基础上进行web开发时必须遵循的抽象约定,只要我们按照这个约定来,一个正常的前台请求就能准确的走到Contorller对应的Action,在处理完数据后跳转到相应的视图进行展示,也就是依赖倒置。
因此有时我们也称依赖倒置原则为
好莱坞原则
Don't call me, I'll call you.
你(低层/应用代码)不要调用我(高层/框架),我(高层/框架)会调用你(低层/应用代码)
参考:
https://www.oodesign.com/dependency-inversion-principle.html
评论