架构师训练营第二周作业
1. 依赖倒置(DIP)
1、高层模块不能依赖低层模块,而是大家都依赖抽象
2、抽象不能依赖实现,而是实现依赖抽象
我的理解就是高层模块把主动权掌握在自己的手里,低层模块按照高层模块的规范来进行实现,高层需要哪个低层模块的时候拿过来用就好。就类似于好莱坞原则:不要给我们打电话,我们会打电话给你(don't call us, we'll call you),每一个演员(也是具体实现)只能被动的接受公司(也就是制定规范的高层)的选择。
2. dubbo实现依赖倒置
dubbo的spi其实就是实现依赖倒置的一个典型案例,我们就拿dubbo(版本2.5.x)注册中心来说,我们通过源码其实可以看到dubbo可以依赖的注册中心有Redis、zookeeper、广播以及默认的内存实现,他们都依赖于RegistryService的接口进行实现。如下图所示:
而在dubbo服务暴露的时候,会把服务注册到服务中心,我们可以看一下RegistryProtocol的实现(为什么会选择RegistryProtocol其实也是dubbo的spi机制起了作用),在进行export的时候会调用RegistryService的register进行注册,而运行期具体是选择zookeeper还是redis是在我们配置文件中定义注册中心的时候就可以定好(比如在配置中心定义<dubbo:registry address="zookeeper://127.0.0.1:2181"/>)。采用了这种机制,在我们的服务配置的这一高层模块就不会依赖具体的实现,只需要依赖接口,而下层只需要实现这个接口供高层模块调用。比如现在增加需求,需要支持nacos注册中心,只需要实现RegistryService的接口,而高层模块不用修改任何代码,就可以很轻松的使用nacos。所以这就是依赖倒置所带来的好处。
3.接口分离
cache 实现类中有四个方法,其中 put get delete 方法是需要暴露给应用程序的,rebuild 方法是需要暴露给系统进行远程调用的。如果将 rebuild 暴露给应用程序,应用程序可能会错误调用 rebuild 方法,导致 cache 服务失效。按照接口隔离原则:不应该强迫客户程序依赖它们不需要的方法。也就是说,应该使 cache 类实现两个接口,一个接口包含 get put delete 暴露给应用程序,一个接口包含 rebuild 暴露给系统远程调用。从而实现接口隔离,使应用程序看不到 rebuild 方法。依据上面说明,拆分后的类图如下:
版权声明: 本文为 InfoQ 作者【olderwei】的原创文章。
原文链接:【http://xie.infoq.cn/article/fabdc17b5878efa74bf131e9d】。文章转载请联系作者。
评论