看完“实现模型”,你是否长吁一声,准备拿起咖啡,惬意的喝上一杯?毕竟我们已经完成了从用例到编码的全过程了,确实是值得庆祝的一件事情,但“革命尚未成功、同志还需努力”,现在还不是享受的时候,接下来我们需要进入“处理模型”阶段。
l “处理模型”阶段的任务
“处理模型”英文是“Process Model”,Process在IT里面又叫“进程”,虽然和进程相关,但直接叫“进程模型”会误导大家,所以我叫它“处理模型”,也就是和处理相关的设计。我们来看看“处理模型”阶段的任务:
1)进程、线程设计;
2)子系统设计;
为什么需要“处理模型”呢?相信看到上面的任务后,聪明的你应该已经知道了原因:
1)随着系统规模增大,处理性能要求增加,必须采用多进程多线程处理方式;
2)随着系统规模增大,复杂度增加,加上需要考虑可扩展性、可测试性、可靠性等质量属性,必须采用“分而治之”的方式划分子系统(注意此时还不是架构设计,欲知详情,请关注下一篇博文);
l 为什么现在才开始进行进程、线程、架构设计?
讲到这里,估计很多朋友都有疑惑了:按照一般的经验,都是最开始就要进行子系统设计、进程线程设计的,怎么你的这个流程到现在才开始进行进程、线程、子系统设计呢?
我们知道:进程、线程、子系统设计都必须有基础,而不是凭空创造或者想象出来的。那种所谓的先画一个圈表示系统、然后再在这个圈下面画几个圈表示子系统、子系统下面再画几个圈表示进程或者线程的自顶向下的设计方式就像“浮沙筑高台”,其实是完全行不通的,为什么呢?
因为这个时候划分子系统没有任何可靠的依据。架构设计、子系统设计、进程线程设计主要是为了解决性能、可靠性、可扩展性、可测试性、安全性等质量属性,而不是客户主要关注的功能属性。性能、可靠性、安全性可以从客户获得,但无法像功能属性那样一步一步的映射到代码(客户说要“每秒支持10000个交易”,然后你画了三个圈,说“这样就可以达到每秒10000个交易”,谁会相信呢?),而可扩展性、可测试性在客户需求阶段根本不会体现。所以我们必须等到“实现模型”完了之后再进行进程、线程、子系统设计、架构设计。
可能大家还有疑问:按照你这个说法,岂不是要等到系统全部编码完成后再来进行进程、线程、架构设计?
回答这个问题的关键词就是“迭代”,第一个迭代(一般都叫做Demo)把最主要、最核心、最关键的需求按照“用例模型”->“领域模型”-> “设计模型”-> “实现模型”->“处理模型”走一遍流程,这样第一个迭代就可以把架构、子系统、进程、线程初步设计完毕,后续的迭代基本上只要走“用例模型”-> “设计模型”-> “实现模型”就可以了,即使有调整也不会太大,因为第一个迭代式把最主要、最核心、最关键的需求给实现了。
l 具体如何操作?
我们来看如何基于“实现模型”进行进程、线程、架构设计:
1)第一步:将已有的对象进行分组;
分组的原则其实就是大家常见的“高内聚、低耦合”,把最相关的、联系最紧密的对象划分到同一组;
2)第二步:将多个组划分为进程、线程;
将对象组再分组划分到具体的进程和线程,分组的原则主要看性能要求(响应时间、吞吐量),性能数据可以基于已有的“实现模型”进行评估或者测试。
3)第三步:设计进程的同步、通信;
既然是多进程、多线程,就必须设计出进程间同步和通信方式。
4)第四步:将进程划分到不同的子系统;
结合根据“高内聚、低耦合”的原则、以及性能、可靠性、可扩展性、可测试性等质量属性要求,将进程划分到不同的子系统;划分子系统也为下一个阶段(卖个关子,先不说:-P)打下了基础。
5)第五步:设计子系统间的同步、通信
和第三步类似,划分为不同的子系统后,必须设计子系统间的同步和通信方式。
看起来步骤比较多,不过每个步骤其实都不难,简单点说就是“排列组合”,将对象排列组合成进程线程,将进程排列组合成子系统。
千言万语不如一个用例,我们还是继续前面的POST机样例来看看“处理模型”阶段如何操作吧。
经过“实现模型”阶段后,我们的POST机可能是这样实现的:“商品”、“交易”、“商品管理”、“商品清单”、“付款方式”、“店铺”、“收银机”、“VIP会员”、“供货商”等对象了,接下来我们就要进行“处理模型”设计了:
1)第一步:将已有的对象进行分组;
1.1)“商品”“商品管理”都是商品相关的对象,因此划为第一组,命名为“商品处理”;
1.2)“交易”“商品清单”“付款方式”都是和交易相关的对象,因此划为第二组,命名为“交易处理”;
1.3)“店铺”、“收银机”都是系统静态信息,因此划为第三组,命名为“系统信息管理”;
1.4)“供货商”、“VIP会员”都是第三方的管理信息,因此划为第四组,命名为“第三方管理”
2)第二步:将多个组划分为进程、线程;
初步评估,“商品处理”和“交易处理”的性能要求会很高(因为商品很多,交易也在不断进行),而“系统信息”是一个基本静态的信息,性能要求会很低,而“第三方管理”性能要求相对也不高,因此可以设计出3个进程:“商品处理”进程、“交易处理”进程、“信息管理”进程,其中“信息管理”进程负责 “系统信息管理”和“第三方管理” 两组对象
3)第三步:设计进程的同步、通信;
进程间同步和通信和具体的实现有关,可以参考相关资料,例如Windows和Linux的可以参考我的博文《多核时代:并行程序设计探讨(4)——Windows和Linux对决(进程间通信)》http://blog.csdn.net/yunhua_lee/article/details/4409138
《多核时代:并行程序设计探讨(5)——Windows和Linux对决(进程间同步)》。
4)第四步:将不同的进程划分到不同的子系统;
第二步已经设计出三个进程了(实际情况会更多):“商品处理”进程、“交易处理”进程、“信息管理”进程,因此可以划分为三个子系统:商品管理系统、交易系统、信息系统。其中“信息系统”负责“系统信息管理”和“第三方管理”。
注意:由于此样例比较简单,所以出现了进程和子系统一一对应的情况,实际工作中应该是一个子系统包含1至多个进程。
5)第五步:设计子系统间的同步、通信
和第三步类似,划分为不同的子系统后,必须设计子系统间的同步和通信方式。
由于子系统可以是进程、线程,也可以是独立运行的程序,因此子系统间通信方式也随着实现方式不同而不同。例如程序间通信可以采用共享文件、共享内存、Socket等方式。