UML建模

====一,概述==== UML简介

UML (Unified Modeling Language,统一建模语言),是运用统一的标记和概念来实现面向对象软件分析和设计的一种可视化的建模语言和图形工具。 二,UML、OOAD和RUP等是新事物,普及应用成本还很高。

采用use case driven的OOA(object oriented analysis),你会请使用者确认的文件,当然就是use case。接着你会依据use case,开始进行OOD(object oriented esign)。当你画好sequence diagram, class diagram,你可能会希望客户的信息人员,可以帮忙确认,这些文件所描述的系统,是否正确。

且不提use case在尝试着用文字来描述系统与外界之间的交互作用的过程中,一般会遗漏掉一些系统该做的事(所以才那么强调iterative)。

更普遍性的灾难是而客户/客户信息人员看的无知/误解/误导use case等,还有更致命的争议会来开发方/开发方信息人员的无知/误解/误导,都会带来沟通的障碍和资源的浪费。

1,上不着天——与用户/领域专家无法沟通获得真正的需求

a,难以完整全面地描述企业的分工结构

b,难以从宏观把控业务流程的完整与准确

c,无法从微观把控业务信息的操作过程

d,无法彻底全面描述用户的需求

e,造成信息不对称的“功臣”

2,下不着地——无法提供直接到位的素材指导程序员编程。它不支持直接支持详细设计。

3,一盘散沙——没有在细微之处建立建模图形之间的联系

a,状态转移图中,事件与外部Actor、Class、Package等无关;

b,无法从语法上建立状态转移图与顺序图的联系;

c,无法从语法上活动图应与顺序图在流程描述关系;

d,协作图和顺序图中与Message相伴的参数与类图无关。 三,用UML的OO(对象)模型来帮助设计关系型数据库

UML对象模型在本质上只是一个扩展的实体-关系(ER)模型。他可以从结构,约束和潜在估算三方面来帮助设计数据库。

我们现在用的数据库是关系数据库,非面向对象的数据库。类的方法要在程序代码中实现,数据库表也不是类。只是类的存储采用关系数据库,表现为类定义转变为表定义,类属性转变为表字段,但两者的映射也可以有一些其他方式,存储过程与类方法没有必然联系。等面向对象的数据库实现后,才能把类的属性和方法同时存储到数据库中。

1,结构映射到表:

(1)域(属性类型)映射:

简单域--数据类型和大小

枚举域--通常存储为一个字符串(更复杂的是布尔值/表/编码)

标识符--超过30个类时使用基于存在的标识(自动Id/RDBMS顺序号)。

(2)一个类映射到一个表,一个属性映射到一个列

(3)关联映射:

多对多关联-->一个特别的表(图表2),关联的主键是每个类的主键的合并。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=af51e8&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248274.gif

一对多关联-->一个外键隐藏在“多”表(图表3)。角色名字成为外键属性名字的一部分。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=b90c7d&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248262.gif

零或一对一关联-->把外键隐藏在“零或一”表(图表4)。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=e7d5d8&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248263.gif

其它一对一关联。把外键隐藏在任一表里。

可选的映射:你也可以用特别的表(图表5)来实现一对多和一对一关联。特别的表给了你更统一的设计和更大的扩展性。无论如何,特别的关联表打碎了数据库,并增加了表的数量。此外,特别的关联表不能强迫一个更低的多重性限度为“一”。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=60b4e9&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248264.gif

(4)泛化映射为特别的表。映射超类和每个子类为一个表(图表9)。所有的表共享一个共同的主键。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=d93060&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248265.gif

可选的映射 泛化有几个可选的映射。 消除。你可以优化除去那些除了主键外没有别的属性的类(图表10)。这样减少了表的数量,但提供更少的正规实现。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=79d13f&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248266.gif

减少超类属性。你可以除去超类表并把超类属性复制到每个子类(图表11)。这样可以有描述每个对象为一个表的优势。无论如何,它将引起数据库结构的冗余,你查找一个对象时可能需要搜索多个子类表。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=90912f&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248267.gif

增加子类属性。作为第三个可选项,你可以除去子类表并存储所有的子类属性到超类表里(图表12)。这样用一个表描述每个对象,但干扰了第二范式。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=863f51&media=http%3A%2F%2Ftech.ccidnet.com%2Fpub%2Fattachment%2F2003%2F8%2F248268.gif

(5)定义参考完整性

建立表后就应该定义参考完整性动作来明确对象模型的意义。(不要使用SQL触发器来实现参考完整性!)如果你使用基于存在的标识,你将不需要传播更新的结果。我们建议以下对删除的参考完整性方针:

泛化。级联从泛化实现中产生的外键的删除。

隐藏的关联,最小化多样性为零。正常地把外键设为空,但有时候你可能要禁止删除。

隐藏的关联,最小化多样性为空。你可以级联一个删除的结果或者禁止该删除。

关联表。正常地我们级联关联表里对记录的删除。可是,有时候我们禁止一个删除。

(6)加入索引

实现数据库结构的最后的一步是加入索引来调整数据库快速遍历的性能。正常地,你应该为每个主键和候选键定义一个唯一的索引。(多数RDBMS作为SQL主键和候选键约束的副作用来建立唯一的索引。)你也应该为每个被主键或候选键所约束的外键建立一个索引。你应该在你的数据库开始设计阶段里加入索引。

另外可以考虑范式,但它对于基于面向对象(或实体)的开发不如对基于属性设计的开发那么重要。

2,功能映射到SQL命令。对一个模型检查用例时的遍历表达式可以直接映射到SQL代码。

四,UML辅助网站规划和设计

1,规划–User Case [用例图用法]

(1)用户和角色:实线箭头表示泛化(generalization)关系 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=8feccb&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_01.gif

(2)定义需求:多个Use Case图 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=090e34&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_02.gif

(3)用户界面组织:各个界面之间的转换流程。页面和文件可用相应的构件图(Component Diagram)建模,以下所用的类图(Class Diagram)工具也很方便。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=a9968f&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_03.gif

网站的common区域,你可以看到指针指向的是整个包(package)而不是区域中的单个文件,这是一种减少混乱的简化方法,因为所有其它的包都要用到大部分(如果不是全部的话)/common/区域中的文件。

(4)要用到的工具和技术。 

对于小型网站,特别是由于投资的原因,选择工具和技术相当有限。一般是:Apache,MySQL/PostgreSQL,PHP、Perl或JSP/Servlet。(对于规模较大的网站,在投资应用软件之前,它必须对各种工具进行更严格的评估和测试)。当前最流行的组合是Apache + PHP + MySQL。以下的构件图足够使用。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=341a66&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_04.gif

2,设计阶段(设计阶段应该与分析阶段交迭互动。)

(1)静态模型:类图 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=d1ead9&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_05.gif 说明如下:

Renderer类是一个抽象类(用斜体字显示)。这意味着Renderer类不能直接使用,程序只能创建其子类的实例(即new Region())。为了满足把页面内容显示到不同类型浏览器的需要,所有用来生成内容的页面都必须从Renderer类派生。

WeatherReport类创建并拥有Region对象,这通过代表聚合关系(Aggregate Relationship)的黑色菱形显示出来,它表示一个对象拥有并创建其他对象。

方法名字前面的加号(“+”)表示该方法是公用方法,可以被其他对象或者函数调用;减号(“-”)表示方法或者变量是私有的,只能由同一对象内部的成员函数访问。在PHP中方法和变量是公用的,但我们应该总是把变量看成私有,避免从对象外部直接访问变量。

HTMLWeatherReport类依赖于HTMLUtils类。依赖关系(dependency)表示一个类要创建另一个类的实例或者调用另一个类的方法。

类图中的每一个类应该注明:所有的方法(以及所有的变量,如有的话),方法的访问属性(public,private或者protected),方法的返回值类型,方法的参数,变量的类型。函数写在前面,如果类有变量的话,则一般随后在一个分开的方框中列出。

即使你所构造的不是一个面向对象的系统,你仍就可以用类图建立系统的模型。类能够方便地描述出各种包含关系和你所编写的函数文件。虽然此时类图不再显示继承、构成/聚合等面向对象系统特有的关系,但它可以用依赖关系描述出文件之间的调用关系。

(2)运行时的系统模型:情节图(Scenario Diagram)特别有用。情节图分成两种:协作图(Collaboration Diagram),序列图(Sequence Diagram)。一般地,我们不会建立系统所有交互过程的模型,情节图只用来描述系统最复杂的部分,或用来概括出代码的一般调用模式。例如,我们可能要示范特定的页面如何与验证用户身份的代码协作,或者要显示页面如何调用公用代码(工具性的框架代码)以保持统一的外观和风格。

协作图和序列图分别举例如下。

http://www.yesky.com/SoftChannel/72342376189788160/20021114/softfz201114_06.

一般而言,用“1,1.1,1.2,2,2.1,……”的形式显示出调用栈的深度是一种更好的选择 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=aca947&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_07.gif'

就图形所传达的信息而言,次序图和协作图非常相似。事实上,许多UML建模工具能够从协作图生成次序图,或者相反。次序图与协作图的主要不同之处在于:在次序图上,事件的发生次序一目了然,非常直观。另外,次序图中还可以加入生存周期和时间方面的详细信息,比如延迟、线程并发、对象的构造和删除等。

在决定选用次序图还是协作图的时候,考虑以下几点有助于你作出最合适的选择:

如果要显示代码中与时间或线程密切相关的问题,选择次序图。

如果要显示对象之间的交互模式,选择协作图。

如果要显示几个或者大量对象之间的交互过程,选择次序图。

如果要显示少量对象之间的大量消息传递或交互过程,选择协作图。

(3) 应用部署的规划

部署图(Deployment Diagram)在两个方面仍旧很有用:网站结构,文件组织。对于文件组织,前面讨论界面规划时已经提到它也可以用类建模工具进行规划。下面给出一个简单的构件图供参考,但根据网站的需要和复杂程度的不同,你可能不需要它。 http://www.deepcast.net/wiki/lib/exe/fetch.php?hash=32a9b0&media=http%3A%2F%2Fwww.yesky.com%2FSoftChannel%2F72342376189788160%2F20021114%2Fsoftfz201114_08.gif'

3,设计原则:UML只是一个工具。如果使用得法,UML能够帮助我们轻松地构造出更好的网站。然而,要设计出优秀的网站,关键仍在于要有一个好的面向对象设计原则或理念--“提高类的内聚力,减少不同类之间的联系”

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

UML简介

用例图用法

参考资料:

UML建模工具集|

选择一种UML建模工具 http://www.cnblogs.com/voyage/archive/2004/07/04.html 面向对象的关系数据库设计http://263.aka.org.cn/Magazine/Aka2/objdb.html UML在关系型数据库设计中的应用http://it.icxo.com/htmlnews/2004/08/26/309015.htm 使用 UML 为 Web 应用程序构架建模http://it.icxo.com/htmlnews/2004/08/06/287532.htm UML辅助网站规划和设计指南http://www.yesky.com/SoftChannel/72342376189788160/20021114/1639975_1.shtml 统一用例方法www.uml.org.cn/oobject/images/UUCMvA0.pdf