设计原则之依赖倒置和接口隔离
依赖倒置
依赖倒置原则,英文是Dependency Inversion Principle, 缩写为DIP。
依赖倒置原则主要有两层含义:
高层模块不要依赖低层模块,而是大家都依赖于抽象
抽象不能依赖实现,而是实现依赖抽象
在调用链上,调用者属于高层,被调用者属于低层。
一般业务开发中,往往是高层模块调用低层模块,这时高层模块依赖低层模块是没有问题的。但是在框架的设计中,框架是不是清楚业务实现的,因此无法依赖低层模块。
依赖倒置原则通常用于指导框架的设计。框架层调用业务层的代码,因而框架属于高层,而业务属于低层。框架并不是直接调用业务层,而是通过定义接口(抽象),业务实现接口,而框架层通过接口调用业务层。框架的设计是要满足好莱坞原则的,即由我来调用你,你不要调用我(don't call me, I'll call you),因此依赖倒置原则有时也叫好莱坞原则。
例如Tomcat, Java Web应用程序运行容器。编写好的web应用部署在Tomcat里,便可以被Tomcat调用并执行。Tomcat属于高层, web应用程序属于低层,但是Tomcat与 web应用之间没有直接的代码依赖,他们都依赖于Servlet规范,即一个抽象。Servlet是一个规范,不依赖于任何实现,而Tomcat和web应用程序都依赖Servlet规范,满足依赖倒置原则。
接口隔离
接口隔离原则,英文是 Interface Segregation Principle,缩短是ISP。
接口隔离表示不应该强迫客户程序 依赖它们不需要的方法。
例如下面的Cache类:
Cache中的方法可以归为两类:
对缓存的操作:get(), put() 和 delete();
配置缓存: reBuild()
两类接口的应用场合往往是不一样的,实现的地方也可以不一样。如果使用方只想实现对缓存操作的接口,而不做配置,保持默认。这时调用方依赖需要实现reBuild()接口,这就违反了接口隔离原则。
更佳的做法是将上面两类接口分别放在两个不同的接口类中,使用方可以根据具体需要有选择地实现不同的接口。
优化后的类图如下:
优化后的设计,看似满足接口隔离原则,但是使用时会觉得很难用。
我们先理清几个问题:
谁使用ICache?
谁实现ICache?
谁使用IConfig?
谁实现Iconfig?
ICache应该是由缓存使用方使用, 由缓存提供方实现;而IConfig应该由缓存使用方实现,用于自定义缓存配置,而由缓存提供方使用,用于接收缓存使用方的自定义配置。
因此,进一步优化后的方案如下:
评论