模块之间紧耦合是一件坏事情,无论你是否使用OSGI这些模块化技术,在套入模块技术之前,你必须从设计高度来降低模块之间的耦合。
Fun With Modules一文提出了几种模块松耦合方法,最佳事件或称为模式吧:Escalation Demotion 和Callback。
该文以Customer和Bill这个简单案例为例子,其模型类图如下:

将这两个模型及其相关类打包到两个Jar包中:cust.jar 和 bill.jar
使用JarAnalyzer 这个工具可以帮助我们分析出Jar包之间的依赖关系,如下图:

从图中可以看出,这两个包其实是存在循环相互依赖。
Escalation
升级抽象,将设计提高一个层次来降低依赖,解决上面案例的循环依赖,还需要从为什么产生循环依赖这个原因下手:
一个Customer有多个Bill实例. 当Bill的支付方法被调用时,Bill需要决定是否使用折扣, 但是折扣率是Bill的一个特性字段,不是Bill的. 这样,Bill类就要调用Customer的方法来决定折扣率。
但是从业务讲,也不能将折扣率从Customer移植到Bill中,因为不同客户确实有不同折扣率,是其自身一个特性。
那么,为了截断这种循环依赖,我们建立一个类为CustomerMediator,这个中介者mediator封装了折扣的计算,然后将结果递交给Bill类,结果如下:

mediator.jar被直接和客户端打交道,升级到cust.jar和bill.jar之上了。
Demotion
升级是一种办法,反过来降级也是一种解耦方式,在上面案例中,我们引入一个DiscountCalculator ,如下类图:

Customer可以作为DiscountCalculator的工厂,因为它有DiscountCalculator输入值折扣率。
这样,我们得到如下模块依赖图:

大家会发现,在这个案例中降级办法比较合适,无论升级还是降级,合适办法取决于业务场景上下文。
待续...