应该感谢那些指出你错误的人

借我三千虎骑,复我泱泱中华!

博客园 首页 新随笔 联系 订阅 管理

3.2 运行时的系统模型


有些时候,我们需要显示出应用的各个部件如何在运行时协作完成任务。前面的类图显示了类之间的关系,但它没有显示出调用出现的次序,也没有显示出来自一个函数的结果可能决定下一次调用的目标。为了在更动态的层面上描述系统,UML提供了许多其他类型的图。对于Web网站设计来说,情节图(Scenario Diagram)特别有用。情节图分成两种:协作图(Collaboration Diagram),序列图(Sequence Diagram)。一般地,我们不会建立系统所有交互过程的模型,情节图只用来描述系统最复杂的部分,或用来概括出代码的一般调用模式。例如,我们可能要示范特定的页面如何与验证用户身份的代码协作,或者要显示页面如何调用公用代码(工具性的框架代码)以保持统一的外观和风格。
协作图和序列图分别举例如下。

图6:协作图

上面的协作图显示了从Web网站获取天气报表的一般过程。注意该图忽略了一些不重要的方法,因为我们只对处理过程中的关键步骤感兴趣。你可以根据编号“1”到“1.3.3.4”找出各个函数的执行次序。一些人喜欢以“1,2,3,……”形式对执行步骤编号,但一般而言,用“1,1.1,1.2,2,2.1,……”的形式显示出调用栈的深度是一种更好的选择,这种编号方式能够更清楚地显示出程序的控制转换过程。例如,上图显示出report()方法调用了WMLUtil以及Region对象中的许多方法:在通过一系列的查询和内容生成函数为指定地区生成报表之前,我们调用了WMLUtil中的buildHeader(...)函数;最后我们调用的是WMLUtil模块的buildFooter(...),然后返回report()方法,最后返回getPage()。你可以为协作图加上更多的细节说明,比如返回值、约束、条件等。

图7:序列图

就图形所传达的信息而言,次序图和协作图非常相似。事实上,许多UML建模工具能够从协作图生成次序图,或者相反。次序图与协作图的主要不同之处在于:在次序图上,事件的发生次序一目了然,非常直观。另外,次序图中还可以加入生存周期和时间方面的详细信息,比如延迟、线程并发、对象的构造和删除等。
在决定选用次序图还是协作图的时候,考虑以下几点有助于你作出最合适的选择:
  • 如果要显示代码中与时间或线程密切相关的问题,选择次序图。
  • 如果要显示对象之间的交互模式,选择协作图。
  • 如果要显示几个或者大量对象之间的交互过程,选择次序图。
  • 如果要显示少量对象之间的大量消息传递或交互过程,选择协作图。

3.3 应用部署的规划


正如本文前面“工具选择”部分所提到的,大多数Web网站的体系结构并不复杂。尽管如此,部署图(Deployment Diagram)在两个方面仍旧很有用:网站结构,文件组织。对于文件组织,前面讨论界面规划时已经提到它也可以用类建模工具进行规划。下面给出一个简单的构件图供参考,但根据网站的需要和复杂程度的不同,你可能不需要它。

图8:构件图

3.4 设计原则


UML只是一个工具。如果使用得法,UML能够帮助我们轻松地构造出更好的网站。然而,要设计出优秀的网站,关键仍在于要有一个好的设计原则或理念。
“提高类的内聚力,减少不同类之间的联系”这一点在谈到好的面向对象设计原则时经常被反复引用。一个内聚的类包含那些在目标和作用域上都紧密相关的行为和信息。它意味着你不应该把构造UI的代码和实现数学算法的代码混合到一起,你应该尽力把所有与用户紧密相关的信息封装到UserAccount类。内聚式设计是一个重要的设计原则,原因有很多:它有助于减少类之间的依赖关系,使得设计更直观、更容易理解,方便了向其他开发者介绍整个设计,减少了开发者同一时刻需要操作的类的数量,等等。例如,如果你要改变网站的用户身份验证机制,只修改单个文件中的一个类无疑要比修改多个文件、多个类更加方便。
“减少不同类之间的联系”意味着使类或者文件之间的交互减到最少。它不仅使得整个设计容易理解,而且也方便了代码的维护。请考虑下面这个例子:

图9:设计实例A

除非深入了解了上述各个类的用途,要估计这些类的内聚程度是不可能的。然而,从这些类之间的关系可以看出,这个设计方案已经成功地减少了不同类之间的联系。类之间的交互被减到了最少,从而使得系统的行为很容易理解。更重要的是,修改任意一个类时受影响的类数量都减到了最少(例如,修改D类只直接影响B类)。另外,要访问D类中的功能,我们无需知道任何有关E、F或G类的情况。作为比较,请考虑下图:

图10 设计实例B

显然,在这个设计实例中,类之间的联系是相当紧密的。一旦对D1类作了修改,为了检查这种修改对其他类的影响,我们必须对其他类进行广泛的测试。
只有在实践中不断锻炼才能避免出现过于复杂的设计,但注意以下几点有助于达到这一目标:
  • 提高类的内聚力。不要把密切相关的功能分散到多个文件和类之中。
  • 采用直观、有意义的名字。如果其他人不能了解类、函数或者变量的作用,不管类的结构是多么完美,整个设计仍缺乏直观性。过多地采用缩写词会影响设计的可理解性。
  • 不要害怕改写代码。有些时候,在几个类之间移动一些函数能够大大地简化代码。
  • 类应该保持紧凑、简洁。代码膨胀是类缺乏内聚力的一种征兆。过于庞大的类、模块或者文件往往缺乏明确的用途和目标。
  • 让其他人复查你的设计。其他人可能有新的想法,或者为你指出你以为显而易见但别人却不能明白的问题。
  • 在早期设计阶段不要考虑太多的性能问题。与一个笨拙的、为了昨天所出现的问题而优化的设计相比,一个简洁、经过精心调整的设计更容易进行性能优化。注意这并不是建议把性能问题抛到脑后,而是建议把细节优化问题留到工程后期考虑。

四、UML工具


下面是一些值得考虑的UML建模工具:
  • Microsoft Visio:Visio Professional 2000现在开始提供内建的UML支持。如果考虑Visio绘图工具的其他各种用途,这是一个相当有价值的工具。如果你使用2000以前的版本,你可以在这里找到Visio Stencil and Template for UML
  • Rational Rose:这是一个推荐使用的工具,但对于许多小型Web工程来说它显得很昂贵。有了Rational Rose这样的工具,改进和维护设计、从模型生成报表、在平行协作环境中与他人共同进行建模工作就很方便了。
  • MagicDraw:一个基于Java的廉价UML建模工具。
  • Together:与C/C++和Java联系密切,支持UML建模。
  • Objecteering UML:一个免费的个人UML产品。
  • System Architect:一个很受欢迎的高端UML建模工具,支持双向工程(Round-trip Engineering)。

五、附录:常用UML符号和参考资源


下面这个表格简要介绍了常用的UML符号和关系。要了解有关UML概念和各种面向对象术语的详细说明,请参见后面的参考资源。
符号
posted on 2006-04-22 11:11  落拓孤鸿  阅读(203)  评论(0编辑  收藏  举报