牛骨文教育服务平台(让学习变的简单)

连载:面向对象葵花宝典:思想、技巧与实践(27) - 动态模型设计

类模型指导我们如何声明类,动态模型指导我们如何实现类

动态模型设计一般都是在类模型设计完成后才开始,因为动态模型设计的时候一般都需要用到类模型中的类。相对类模型来说,动态模型要相对简单一些,主要原因在于动态模型设计的时候没有什么设计原则和设计模式需要应用,只需要对照用例模型,根据用例模型的特点,选取一个合适的动态模型将其表述出来即可。

动态模型在实际开发过程中有非常重要的作用,简单来说,如果没有动态模型,那么你虽然完成了类设计,但还是不能编码,或者只能编写类的声明代码(类属性、方法名称),但不能写类的实现代码(方法里面的实现逻辑,即:每个方法的实现)。动态模型就是用来指导我们如何编写具体的方法的。

 

有的同学可能会有疑问:那些地方要进行动态模型设计呢?

还是那句老话,你觉得比较复杂你就设计,简单你就不设计,总之:你需要你就设计

像我在实际开发中,基本上一个中等项目就一两个业务设计动态模型(小项目看到需求就编码了 :) ),其它业务看需求文档就能看出如何编码,这也是有经验和经验不足的差别。

参考UML标准,常见的动态模型如下:

【状态模型】

状态模型主要用于描述对象的生命周期的状态变化。通过状态图,我们可以了解到对象有哪些状态,状态之间如何转换,转换的触发条件等。当我们发现一个对象的状态比较复杂的时候,就需要设计对象的状态模型。

UML中使用状态图来描述状态模型

【活动模型】

活动模型主要用于描述一个工作流程或者计算流程。其关注点是在完成某项工作的过程中,系统中的哪些对象承担了什么样的任务、做了什么处理,以及这些对象之间的先后交互关系。当我们发现一个处理流程比较复杂的时候,就需要设计流程的活动模型。

UML中使用活动图来描述活动模型

【序列模型】

序列模型主要用于描述对象按照时间顺序组织的消息交互过程,其关键特征是强调按照“时间顺序”来组织对象的交互,所以序列图有时又称为“时序图”或者“顺序图”。序列模型是我们最常用的动态模型,特别适合将用例模型或者SSD转换为系统的动态模型。

UML中使用序列图来描述序列模型

【协作模型】

协作模型主要用于描述按照对象之间的关联来组织的消息交互过程,其关键特征是强调“对象关系”来组织对象的交互。协作模型的作用和序列模型一样,只是强调的点不同,大部分的时候我们都是选择“序列模型”,因为序列模型的时间顺序很多时候和用例模型的步骤不谋而合。

UML中使用协助图来描述协作模型

注意:以上模型并不是每个都必须有的,根据实际需要选择即可

建模实践

以上这些模型都可以从用例模型推导出来,活动模型、序列模型、协作模型基本上都是和用例模型一一对应的,或者对应用例中的某个分支。一般情况下不推荐一个模型中包含多个分支,因为这样会导致图比较复杂,而且主题不突出。

 

状态模型和其它模型相比要复杂一些,因为并不能从单个用例或者单个用例分支推导出某个对象的所有状态,而需要综合多个用例模型,从中提取出和某个对象状态相关的内容,再统一设计状态模型。

 

从用例模型推导出动态模型是一个“分解和分配”的过程,因为在用例模型中,系统是当做一个“黑盒”来看待的,而在动态模型中,系统不再是一个黑盒,而是分解成了一个一个的类。因此我们需要将原来笼统的划分给系统的功能和职责,进一步分解并分配给不同的类。通俗的讲,动态模型就是说:为了完成系统的XXX功能, 先需要类A做任务1,然后需要类B需要做任务2,再由类C做任务3。。。。。。依次分解下去,最终就能够实现将类串起来,相互配合,最后实现了系统的需求。

 

我们以POS机为例,假设我们基于买单这个用例的正常分支设计“序列模型”,则可以得到如下的“序列模型”:

有了上面这个“序列图”,假设我们要开始写代码,则基本可以按照如下伪码的方式实现(实际的编码肯定不会这么简单,但方法是一样):

main(){

    Trade trade = new Trade();                
    Integer tradeId =trade.makeNewTrade();  //创建
    trade.addGoods();                       //增加商品
    trade.cacuMoney();                      //计算总额
    ............//省略一大段代码
    Receipt receipt = new Receipt();        
    receipt.print(trade);                   //打印小票
	...........//省略一大段代码
	trade.finish();                         //结束
}