这里的OO Principles是指Robert C. Martin提出的那一系列原则,如SRP,OCP等; 本文旨在从构建、发布java程序的角度理解这些原则,更具体一点,就是
要找出违背这些原则会对java程序的构建、发布等过程造成什么困扰。
首先可以先罗列一下构建、发布过程中可能出现的坏现象:
1. 编译、打包时间过长
2. 打出的包过大,导致网络传输久、应用启动慢、虚拟机方法区空间被浪费
3. 打出的包里有相同的库,如spring 2.5和spring2.0同时出现
4. 频繁发布应用,浪费时间,影响可用性
5. 做太多的回归测试
6. 发布前夕发现错误,不得不回滚
待续。。。
接下来进入正题,
逐个看下违反OO Principle的后果
(我们会用
caller代表模块的调用者,
callee代表被调用的模块)
1.
违反SRP
场景: callee有两个互不相关的职责r1, r2; caller1依赖r1, caller2依赖r2.
后果:
a.
caller因为callee中的无关代码而浪费构建自己的时间和空间。caller1与callee共同编译时,也需要编译r2相关的代码;但r2部分的代码caller1并不需要,这就意味着编译时间和打包空间的浪费 — 当然,这个浪费可能很小
b.
caller因为callee中的无关第三方库,而浪费构建自己的时间和空间。 如果r2依赖了一些第三方库,而这些库又依赖了另一些第三库,打包caller1时就要把这些只能r2相关的第三方库统统纳入进来,造成打包时间过长、打出的包过大
c.
第三方库太多增加了callee包中库冲突的几率。如果r1依赖了spring 2.5, r2依赖了spring 2.0,callee在打包前就必须进行依赖调解,即两个spring只能留一个;你要么手动确定留哪个,要么通过Maven之类的依赖管理工具来处理;但不管怎么搞,都会比较繁琐,并且带来风险(maven环境中,一个极端情况就是,r1使用了官方的spring坐标,而r2使用了一个山寨的spring坐标)
d.
callee的部分升级导致无关caller的回归测试。为了满足caller2的新功能,r2被升级了,这也意味着整个callee的升级;如果callee没有版本机制,则callee的更新会导致caller1不得不接受新的callee,并不得不做一下回归测试
e.
callee的部分升级导致无关caller在callee发布时不可用。如果callee是一个web service,r2的代码升级意味着整个callee web service都要重新发布,重发过程中不但caller2不可用(使用了灰度发布除外),caller1也会不可用
f.
发布过程中因部分回滚导致整体回滚. 假设callee某次的改动同时包含了r1和r2的改动,在发布前夕,突然发现r2的改动有错误需要回滚,则整个callee都要暂时回滚,再重新构建callee使之只包含r1的改动,然后再次发布
待续。。。