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概念和各种面向对象术语的详细说明,请参见后面的参考资源。

符号 说明
Package
包。用来聚集和组织模型中的一个部分(Use Case,类,等等)。  
Actor
参与者。它代表一个用户或者其他外部的激励器。  
Use Case
用例。Use Case描述了系统某一部分的行为。一般地,Use Case记录对某个系统功能的需求,而这个功能由对动作或者事件的应答示范。  
<<include></include>> Relationship
包含关系。标注为<<include></include>>关系的Use Case关系能够引入其他Use Case的功能。这是一种方便的分割Use Case、避免单个Use Case过于庞大的方法。  
<<extend></extend>> Relationship
扩充关系。标注为<<extend></extend>>关系的Use Case关系能够在不重复现有Use Case的各种描述和需求的情况下,使现有Use Case的行为特殊化。  
Dependency
依赖。正如其字面意义,它表示一个事物依赖另一个事物。这意味着一个事物了解另一个事物,并需要另外一个事物才能发挥功能。  
Note
注解。在UML图中提供注解的目的是以简短的说明阐明图表的内容。  
Component
构件。构件一般代表一个软件单元,它可能是一个DLL、一个执行文件,或者是一个数据库  
Node
节点。节点一般代表一台机器,这台机器具有运行一个或者多个系统构件的能力。  
Class
类。UML中的类与面向对象编程中的类一样,即它定义并封装了一组行为和属性。类在运行时被实例化从而创建出对象。  
Object
对象。对象是类的实例。例如,“MyClass myObj = new MyClass; ”创建了一个myObj对象。  
Generalization
泛化。父类能够派生出(或称为特殊化)具有更多特殊行为的子类,此时父类即为子类的超类(或子类的泛化版本)。  
Interface
接口。接口定义了一组可以从外部访问的行为。类、库、执行文件、数据文件都可以由接口来描述。接口本身并不实现任何功能,它只是和声明实现该接口的对象订立了一个必须实现哪些行为的契约。  
Abstract Class
抽象类。抽象类不能直接实例化,但允许派生出具体的、有实际功能的类。  
Association
关联。关联就是把两个或以上的类连接起来。你可以为两个类之间的这种关系提供更具体的信息。关联是两个或多个特定类元之间的关系,它描述了这些类元的实例的联系。在一个关联中同一个类可以出现在多个位置上。  
Aggregation
聚合。聚合关系表示某个对象属于其他对象所有。  

  参考资源:

]]>