Spring和AOP像一个强力的粘合剂,将完全独立开发的组件(或说是模块,下同)粘合成一个有机的,完整的,可扩展的系统。正是有了这个粘合剂的帮助,才实现了比较彻底的独立组件开发。
说它是“比较彻底”,是因为它极大的减少了组件之间的依赖。在你开发一个组件时,基本上不会因为其它组件没有开发完成,或出现Bug而影响到你的进度。
但是,它并没有完全消除开发时组件之间的依赖,你仍然得依赖于其它组件提供的API接口。为此,我们不得不把一个组件拆成两个jar包:一个component-api.jar,一个component-impl.jar。由于api包内全是公用接口和Value Object,所以它相对稳定,可以早早的提供出来。这样,一个组件如果要使用另一个组件的服务,在开发阶段,只须依赖于api包即可。运行时,Spring再根据服务提供组件的配置信息找到正确的实现类。
昨天,我们在一个讨论会上发现了一个有趣的问题:
组件UIA是一个UI组件,它要求提供一些数据,于时它把自己的要求写时接口ProviderA中。组件C1和C2是两个不同的业务组件,它们的UI中都有使用UIA这个组件,而它们都提供了自己的数据接口ServiceC1和ServiceC2。
ProviderA所要求的方法,在ServiceC1和ServiceC2中都有提供。这个时候怎么做才能使各个组件完独立呢。
一、让ServiceC1和ServiceC2继承于ProviderA。但是这样将导致业务组件依赖于UI组件。有谁知道一共有多少个UI组件需要依赖啊?而且UI组件是最易变的。
二、把ProviderA从uia.jar抽出来,放到单独的uia-api.jar中。这个就未免小题大做了。一个系统少说也有几十个UI组件,难道要生成上百个jar包不成?
三、把所有的UI的要求的API都抽出来,放到一个ui-api.jar中。这样jar包是少了,可是单个的UI组件就失去独立性了。
上面三个方案,不管怎么管理UI组件的接口,都没有解决业务组件依赖于不定数目的UI组件这个问题。
最后,我们采用的方法是:把UI组件视为某个业务组件的子组件,UI组件自己不定义接口。所有对外的接口和对UI的接口,都放在业务组件的api包中。
这样做,业务组件和UI组件都依赖于api包,互相之间没有依赖。当然,这样做,UI组件就不能游离于大的业务组件之外。而我们采用这个方案的原因也在于,我们认定为多个组件提供服务的UI组件是很少的。
显然我们采用的方法只是就事论事的一个折衷方案。并没有解决服务提供者和消费者之间的交叉依赖。
要解决这种交叉依赖,我的思路是再提供一个接口之间的粘合机制。消费者定义自己要求的服务接口,提供者定义自己提供的服务接口。最后用一个配置文件,将二者粘合起来。
目前,Spring还没有提供这种功能。