面向对象设计原则 ---- 依赖倒置原则(DIP)
DIP:Dependency Inversion Principle
高层模块不能依赖底层模块,高层模块和底层模块,都依赖抽象。(抽象位于高层模块,抽象和高层模块位于同一层次)
抽象不能依赖实现,而是实现依赖抽象。
DIP 倒置了什么?
模块和包的依赖关系
开发顺序和职责
软件的层次化
高层决定低层
高层被重用
解读:对比(面向过程和面向对象)
1.面向过程:典型高层依赖底层。高层的功能实现,完全依赖低层,才能完成软件运行。低层变动,倒逼高层跟着变动。
低层模块 Utility Layer:可被重用,高层模块的重用性降低。
低层模块 Utility Layer 修改,导致高层模块必须修改,才能使用低层模块。
2.面向对象:高层不再依赖低层,高层依赖抽象,低层实现依赖抽象。
高层依赖抽象,抽象属于高层(抽象与高层位于同一层次),针对抽象编程====>高层稳定. 低层实现高层抽象。低层扩展,不会倒逼高层变动。
违反 DIP 案例:
问题:高层模块 Button,直接依赖低层模块 Lamp。 依据 DIP 原则,如何进行改进,使高层模块 Button 不再依赖低层模块 Lamp?
分析:Button 属于高层,要使 Button 依赖于同级别或者同层次的抽象,要进行抽象。Button 依赖同层抽象,低层 Lamp 实现抽象。抽象结果如下:
框架核心:框架定义接口,应用代码实现接口。框架调用代码,代码不要调用框架。
好莱坞规则----- Don't call me,I'll call you--------倒转层次依赖关系
解析:框架特点:
框架调用应用程序,应用程序不会去调用框架。框架不依赖应用程序,
比如:Tomcat Web 服务器框架。
Tomcat 框架调用 Web 应用程序,但是 Web 应用程序不会反过来调用 Tomcat。-----好莱坞原则
Tomcat 框架依赖 J2EE 抽象,J2EE 抽象属于 Tomcat 框架层面。-------DIP 体现:高层依赖抽象,针对接口编程。
J2EE 规范定义了 servlet,web.xml 规范,Tomcat 基于 servlet 和 web.xml 编程:
Tomcat 监听 HTTP 请求,抽取数据包解析为 request,response,依据 web.xml,获得 servlet 接口,再将参数传递给 servlet 的 doGet 或者 doPost 方法。
Tomcat 框架基于 servlet 接口编程,框架里面没有实现 servlet 接口,应用程序实现 servlet 接口。
运行时,Tomcat 高层调用实现 servlet 接口的低层应用程序,但是应用程序不调用 Tomcat 框架。
比如其他框架:Junit,Spring
架构师核心技能:框架设计
评论