依赖倒置原则
什么是依赖倒置原则
该原则主要包含两点:
高层模块不应该依赖低层模块,两者都应该依赖其抽象;
抽象不应该依赖细节,细节应该依赖抽象
为了实现这两点需要在从高层和低层, 拓展出抽象层;
最佳实践:
当A模块调用B模块的时候,A不是直接引用B的代码直接调用,而是A模块定义好需要调用的接口,B来实现这个接口,来实现高层模块不依赖低层模块实现解耦
为什么有时候又称为好莱坞原则?
该原则是和好莱坞模式类似,don't call me ,i will call you。
依赖倒置原则实现
非依赖倒置
依赖倒置后:
组件依赖
包划分和依赖:
更好的做法是提取抽象层专用的包.
应用
Model View Controller
UI和ApplicationLayer软件包主要包含具体的类。
控制器包含abstracts/interface类型。
UI拥有ICustomerHandler的实例。
所有包装在物理上都是分开的。
在ApplicationLayer中,有一个Page类将使用的具体实现。该接口的实例由Factory动态创建(可能在同一Controllers包中)。
具体类型Page和CustomerHandler彼此不依赖, 但都依赖于ICustomerHandler。
直接的效果是
UI不需要引用ApplicationLayer或实现ICustomerHandler的任何具体包。
具体类将使用反射加载。
任何时候都可以在不更改UI类的情况下,用其他具体实现替换具体实现。
另一个有趣的可能性是Page类实现了接口IPageViewer,该接口可以作为参数传递给ICustomerHandler方法。然后,具体实现可以与UI进行通信而无需具体依赖。同样,两者都通过接口链接。
spring 实现
spring 通过 DI, 给对象依赖的接口注入具体的实现
包含三种写法:
构造函数传递依赖对象
Setter方法传递依赖对象
接口声明传递依赖对象
Spring 宣扬的是非侵入性的方式,以一种完全外部化的方式来对待对象依赖关系。在 Spring 里,你可以使用 XML、Spring JavaConfig 或者 Groovy-Spring DSL 来连接对象依赖关系,也可以使用其它的方案,如 Spring-annotations。
guava 实现
Guice 把配置做为你的应用程序模型的首要对象来看待,允许它们存在于你的领域模型代码中。我们使用 Guice 模块来说明需要注入什么东西,然后使用 annotations 来指明需要在什么注入.
你可以使用注入来标记(annotate)类本深(通过 @Inject annotation)。缺点则是(如果你使者么认为的话)你必须在你的领域模型中引入 com.google.inject.*。但它通过元数据编程(metadata programming)来确保了目标的方向性,以及注入的显式语义。
接口隔离原则优化Cache设计
参考
https://en.wikipedia.org/wiki/Dependencyinversionprinciple
http://blog.itpub.net/13270562/viewspace-211676/
评论