浏览 7318 次
锁定老帖子 主题:浅谈系统拆分
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2013-01-25
我感觉拆分系统,和拆分代码,本质上是一样的。小到一个方法,大到几个系统,都是一个从输入到输出的序列 Level 1: public void doSomething(){ System.out.println("111"); System.out.println("222"); System.out.println("333"); } 这种情况是最简单的,所有的代码都在一个方法里,没有任何拆分 Level2: public void m2(){ System.out.println("222"); } public void doSomething(){ System.out.println("111"); m2(); System.out.println("333"); } 效果和Level 1是一样的,只是中间多了一次方法的调用,实际上是内存指针偏移。但比起将所有代码写在一个方法里,这里已经做了最简单的拆分 Level3: public class Class2{ public static void m2(){ System.out.println("222"); } } public class Class1{ public void doSomething(){ System.out.println("111"); Class2.m2(); System.out.println("333"); } } 还是很简单,但是比Level2又多了一层,将部分代码拆分到了另一个类里 直到目前为止,无论拆分与否,所有的代码都在同一个进程里,所以都是本地调用(仅需要偏移内存指针即可),过程类似下图: 这里要补充一点,就JAVA平台来说,凡是要调用的代码在同一个JVM里,且classloader可见,都可以认为是本地调用。不管它是打包在.jar文件里,还是直接存放在classpath里,也不管其源码是否来自一个地方 Level4: 现在,输出222这段逻辑,被拆分到了另外一个系统里 所以,只有通过远程调用(RPC),才能111->222->333了,但是本质并没有改变,还是从输入到输出的一串序列,只是本地调用,和远程调用的区别 事实上,这种区别对调用者来说,常常是透明的 public void doSomething(){ System.out.println("111"); Proxy proxy = getProxy();// Proxy是一个interface proxy.print222ForMe(); System.out.println("333"); } 对这个调用者来说,它并不需要知道proxy的实现来自哪里。这是一次本地调用还是一次远程调用,对调用者来说是透明的。只有在上面的部署图里,才能看出区别 通过这个例子,我想说明的是:核心的问题是逻辑,而不是怎么拆分系统。逻辑不会因为放在一个方法里,或者放在10个不同的系统里,就发生变化。最终的结果都是一样的。同时,当需要思考“为什么要拆分系统”的时候,某种程度上和“为什么要拆分代码”是类似的 实际的设计中,拆分系统一般都是必要的,我认为至少有以下3个方面的好处: 1、复用服务 前面举的例子过于简单了,可能有点无法说明问题。但是想象中间那行 System.out.println("222"); 是一段非常重要的代码,其他很多逻辑都需要它。那么如果它是混杂在一个方法中,应用的其他部分就无法重复地调用它了(复用);而把它抽取出来之后,就可以实现复用 系统拆分也是一样,比如我画的这两张示意图,是用QQ截图功能截成JPG的。为了截这2张图,我只好把QQ给打开了。如果QQ截图被抽取为单独的模块,我就可以单独打开截图功能了;如果腾讯其他的应用也需要实现截图,就可以复用这部分功能了 当然,系统之所以被称为“系统”,而不是“应用”、“模块”、“方法”,是因为它比较大(我认为除此之外,完全是一回事,有输入、输出、逻辑的都是系统) 所以,作为系统,复用的往往不是截图这么小的功能,一般希望能够复用一个完整的服务。比如独立出“用户权限管理系统”,就可以在多个业务系统中,复用“用户校验和鉴权”的服务了。我想这就类似几年前比较流行的一个大词SAAS 2、性能考虑 一个大的系统,往往其中的某个部分,承担了很大的并发压力,或者逻辑运算特别复杂,因此成为系统的性能瓶颈 这时就可以考虑将这部分独立出来,从而实现单独部署,再通过负载均衡等手段,来解决性能的问题 3、逻辑清晰 根据业务上、流程上的不同环节,将整个系统拆分为不同的子系统,在逻辑上会更加清晰,从而更容易在架构上说清楚,或者进一步做优化 暂时想到这3点,欢迎补充 PS:至于源码工程的管理,完全是另一回事了。一个工程可以构建出N个系统;N个工程也可以构建出一个系统。是架构的2个不同角度的视图 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2013-01-25
OOP 有一点就是单一职责,也就是说不要把所有的逻辑揉在一起,要进行职责单一化,增加内聚,减少耦合,提高复用
|
|
返回顶楼 | |
发表时间:2013-01-25
任何系统拆分,在脱离了需求环节上讨论,都是没有意义的。
|
|
返回顶楼 | |
发表时间:2013-01-25
Kisses99 写道 任何系统拆分,在脱离了需求环节上讨论,都是没有意义的。
说得对,很赞同 |
|
返回顶楼 | |
发表时间:2013-01-26
的确,纯粹为了解耦而解耦是没有意义的,解耦之后对程序运行效率是存在一定影响的!
|
|
返回顶楼 | |
发表时间:2013-01-29
1、为什么要拆分?不易做单元测试,不易复用,不宜隔离Bug,不宜进行扩容。
2、拆分的依据?系统瓶颈,业务逻辑分层。 3、拆分的弊端?由本地调用转为远程调用,增加复杂性(如需共享数据,则需要进行通信),引入了网络不可靠性带来的处理。 个人之见,一起讨论。 |
|
返回顶楼 | |
发表时间:2013-01-31
最后修改:2013-01-31
你说的基本都是面向对象的设计思想,系统拆分,首先毋庸置疑是提高了复用性,其二降低了耦合,不会因为强关联导致系统需求更改而大动干戈。其三,拆分可以使事物按多维度发展,从而更根据有扩展性。暂时先想到这么几点....
|
|
返回顶楼 | |