上周完成了
Talend项目的重构任务,此任务是为了解决插件之间的无序依赖。
软件产品的规模总是越来越大,模块越来越多,如果出现了一点影响到后继开发或者维护的迹象,就要果断的进行重构,将项目及时调整到正常轨道上。开发RCP项目中遇到的典型就是随着插件数量的增多,各个插件之间的依赖性越来越强,这时候如果不进行及时调整,任由其发展下去,等到出现了插件循环依赖,再回过头来整改可就不是那么容易了。很有可能还要影响到相关的业务功能部件。
任何软件系统到了一定的规模后,都可能会产生模块间的无序依赖。造成这种后果的原因可以总结为以下几种:
1 封装性不好,随意开放公共类或接口给第三方使用。造成客户代码深度依赖于此模块。
2 各个模块各自为政,没有提取公共的接口到基础模块中,使用此模块功能的代码就必须要依赖于此模块。
3 没有良好的面向接口编程习惯,直接引用被依赖模块的具体类。
4 随意使用singleton模式,只图使用方便,不考虑在设计上是否必要。
对应于Eclipse 插件开发,可以理解为:
1 在plugin.xml文件的runtime项中,不加限制的开放所有Package的访问权限;或者在开发过程中,没有限制,随需随开,不知不觉中加剧了插件间的依赖程度。而且由于降低的访问的门槛,容易养成编程人员的懒惰思想,不利于提高其设计能力。
2 开发初期大多是几个人负责一个模块,各个模块间互不干扰的开发,需要访问其他模块是,典型的做法就是让被使用模块提供一个Singleton的类,然后随心所欲的使用其具体类。负责各模块的人很难在公共基础这一问题上达成共识,或者是根本没有考虑到这一点。没有基础模块的归纳总结,随着业务的增大,很容易就造成插件间的循环依赖。
3 使用别的插件的时候,都是直接使用具体类。对插件全部都是依赖于具体类,而不是依赖于抽象。
可供选择的解决方案如下:
1 构建良好的接口体系,外部插件对本插件的依赖仅限于抽象。
2 提取公共部件到一个基础插件中,其中包括全项目共享的服务和资源。全部插件都依赖于此基础插件。
3 插件不依赖于具体提供服务的插件,而是依赖于基础插件,提供服务的插件将服务注册到基础插件中。这样就构建了一个服务注册,获取体系。减轻了各个插件间的依赖程度,降低了服务提供者和服务使用者之间的耦合。
此体系可通过扩展点机制实现。