DIP、IoC、DI笔记
什么是DIP
摘录自【01】
DIP:依赖倒置原则(Dependence Inversion Principle)
- 高层模块不应该依赖于低层模块。二者都应该依赖于抽象。
抽象不应该依赖于细节。细节应该依赖于抽象。
什么是依赖
依赖,A使用了(调用)B,就叫A依赖了B.
Rational Rose的帮助文档上是这样定义“依赖”关系的:“依赖描述了两个模型元素之间的关系,如果被依赖的模型元素发生变化就会影响到另一个模型元素。
什么是倒置
倒置依赖相对于许多传统的软件开发方法,过程式方法总是倾向于创建一些高层模块依赖于低层模块、策略依赖于细节的软件结构。一个设计良好的面向对象程序,其依赖程序结构相对于传统的过程式方法设计的通常结构而言就是被倒置的。
为什么要DIP
- 高层依赖于低层,会导致高层对低层的修改敏感且不易被复用
- 高层依赖于低层,依赖关系是传递的。会引起层层修改
如何DIP
基本原则:依赖于接口,依赖于抽象
层次化
设计中每个较高层次都要为它所需的服务声明一个接口抽象。较低的的层次实现这些抽象接口。每个高层类都通过该抽象接口使用下一层
倒置接口所有权
接口要随拥有他们的客户(调用者,高层)程序发布,而不是实现他们的服务程序(提供服务者,低层)的程序发布
依赖于抽象
程序中所有的依赖关系都应该止于抽象类或接口
- 任何变量都不该持有一个指向具体类的引用
- 任何类都不该从具体类派生
- 任何方法都不该重写他的任何基类中得已经实现了的方法。
什么是IoC
控制反转:程序的主控权反转,由原来应用程序的控制,反转为由框架控制
早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了,因为大多数应用程序都是由两个或是更多的类通过彼此的合作来实现企业逻辑,这使得每个对象都需要获取与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么这将导致代码高度耦合并且难以维护和调试。[02]
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。[03]
参考
[01]Robert C.Martin Micah Martin《Agile Principles,Patterns,and Practices》2008 人民邮电
[02 ]IoC容器和Dependency Injection模式 (http://insights.thoughtworkers.org/injection/)
[03] 百度百科-控制反转(https://baike.baidu.com/item/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC/1158025)