绘制UML活动图的步骤和要点(转帖)

绘制UML活动图的步骤和要点,转自:http://www.yesky.com/427/1794427.shtml

UML 活动图记录了单个操作或方法的逻辑,单个用户案例,或者单个业务流程的逻辑。要创建一个 UML 活动图,您需要反复执行下列步骤。

  第一步,定义活动图的范围首先应该定义您要对什么建模。单个用户案例力?一个用户案例的一部分?一个包含多个用户案例的商务流程?一个类的单个方法?一旦您定义了您所作图的范围,您应该在其顶部,用一个标注添加标签,指明该图的标题和唯一的标示符。您有可能也想要包括该图的时间甚至作者名。

  第二步,添加起始和结束点每个活动图有一个起始点和结束点,因此您也要马上添加它们。在 《UML 精粹》(UML Distilled) (参见参考资料),Fowler 和 Scott 认为结束点是可选的。有时候一个活动只是一个简单的结束,如果是这种情况,指明其唯一的转变是到一个结束点也是无害的。这样,当其他人阅读您的图时,他或她知道您已经考虑了如何退出这些活动。

  第三步,添加活动如果您正对一个用户案例建模,对每个角色(actor)所发出的主要步骤引入一个活动(该活动可能包括起始步骤,加上对起始步骤系统响应的任何步骤)。如果您正对一个高层的商务流程建模,对每个主要流程引入一个活动,通常为一个用户案例或用户案例包。最后,如果您正对一个方法建模,那么对此引入一个活动是很常见的。

  第四步,添加活动间的转变我的风格总是应该退出一个活动,即使它是转变到一个结束点。一旦一个活动有多个转变时,您必需对每个转变加以相应标示。

  第五步,添加决策点有时候,您所建模的逻辑需要做出一个决策。有可能是需要检查某些事务或比较某些事务。要注意的是,使用决策点是可选的。

  第六步,找出可并行活动之处当两个活动间没有直接的联系,而且它们都必需在第三个活动开始前结束,那它们是可以并行运行的。

关于用ArgoUML和AndroMDA协作工作的问题及答案(转)

(问题,转自:argouml用户邮件列表)

Date: Wed, 15 Mar 2006 15:58:51 +0530

From: ashikali.abdulkhader@wipro.com  Add to Address Book  Add Mobile Alert 

To: users@argouml.tigris.org

Subject: RE: [argouml-users] How to assign an activity diagram to a controller class.

   

Yeah. It works fine now. !!!

Thank you all.

-Ashik

-----Original Message-----

From: Ludovic Maitre [mailto:ludovic.maitre@free.fr]

Sent: Wednesday, March 15, 2006 1:36 AM

To: users@argouml.tigris.org

Subject: Re: [argouml-users] How to assign an activity diagram to a

controller class.

Hi Dashing and Abdulkhader,

See issue http://argouml.tigris.org/issues/show_bug.cgi?id=4005 for

assigning the context of an activity diagram. Should this issue answer

to your question ?

Dashing Meng wrote:

> He,

> A interesting question,I am happy to hear any reply for it too.

>

> Dashing

>

> */ashikali.abdulkhader@wipro.com/* wrote:

>

>     Hi All,

>    

>     I am currently facing the following problem while building the

>     Online-Store application that comes with AndroMDA.

>    

>     My model is developed using ArgoUML. Currently I face two

>     inter-related problems in building the Online-Store model using

>     the Maven plug-in.

>

>     1) Initially I've created the Activity-Graph in the Use-case's

>     namespace. But there is no way in ArgoUML by which I can assign

>     the activity graph to a controller class (As it is there in

>     Magicdraw) for calling deferrable call events in action states.

>     Hence this resulted in Validation Error during model validation

>     process.

>

>     2) The solution provided is to create the activity graph in the

>     namespace of a Class. Hence I created the activity graph in the

>     controller class's namespace and now am getting the validation

>     error that says "A use case should have one and only one activity

>     graph associated with it".

>

>     Kindly help me how I should design my model in ArgoUML (Associate

>     an Activity Graph with a Controller Class as expected by

AndroMDA)

>     so that I would be able to integrate the model with AndroMDA for

>     code generation.

>    

>     -Ashik

>

------------------------------------------------------------------------

>     *From:* Dashing Meng [mailto:learndiary_dashing@yahoo.com]

>     *Sent:* Monday, March 13, 2006 4:51 PM

>     *To:* users@argouml.tigris.org

>     *Subject:* RE: [argouml-users] How to assign an activity diagram

>     to a controller class.

>

>     I think an activity graph can be in the namespace of a operation

>     of the class or a usecase's namespace.can't be in the namespace

of

>     a class.

>    

>     Dashing

>

>     */ashikali.abdulkhader@wipro.com/* wrote:

>

>         Dashing,

>        

>         Thanks for your information..

>        

>         In my case the activity graph is already in a use-case's

>         namespace.

>        

>         Now how do I map it to a class's namespace..Wouldn't it be

>         redundant.

>        

>         If my understanding is right the behavior is for a usecase

and

>         not for a class right?

>        

>         Pls corr ect me if I am wrong.

>        

>         Regards,

>         Ashik

>

------------------------------------------------------------------------

>         *From:* Dashing Meng [mailto:learndiary_dashing@yahoo.com]

>         *Sent:* Monday, March 13, 2006 4:32 PM

>         *To:* users@argouml.tigris.org

>         *Subject:* Re: [argouml-users] How to assign an activity

>         diagram to a controller class.

>

>         Draw the state graph under class's namespace. It is: click a

>         class at left side of window, then choose "create-> new

>         statechart diagram" on the menu.

>         It seems an operation can't be synchronized between the class

>         diagram and the statechart diagram in both two directions?I

>         don't know it very clear.

>        

>         Dashing

>

>         */ashikali.abdulkhader@wipro.com/* wrote:

>

>             Hi all,

>             Does ArgoUML has the feature of assigning a

state/activity

>             graph to a class so that action states can defer

>             operations to the class?< /DIV>

>             This is required for running my model built in AndroMDA.

>             Regards,

>             Ashik

答案:转自argouml问题跟踪系统:http://argouml.tigris.org/issues/long_list.cgi?issuelist=4005

Make activity graph context assignment easier

Issue #: 4005  Component: argouml  Version: 0.20  Platform: PC 

OS/Version: Windows XP  Status: STARTED  Issue type: ENHANCEMENT  Priority: P3 

Resolution:  Assigned to: rastaman  Reporter: waiyung 

Subcomponent: Diagrams  Target milestone:---     

URL:  

Summary: Make activity graph context assignment easier 

Status whiteboard:

Description: 

I am using the Argouml with Andromda extension.

One thing required by Andromda is to assign a controller class as the context of

an activity graph by adding a tag like these, as quote from Andromda's guide:

-----------

 Add a tagged value to the controller, pointing to the use-case, like this:

@andromda.presentation.controller.usecase=My UseCase  (the value is the name of

the use-case).

-----------

I noticed with or without setting this tag, the exported xmi file from argouml

has the following tag within the activity tag:

-----------

   <UML:StateMachine.context>

                    <UML:UseCase xmi.idref = '.:0000000000000EB9'/>

   </UML:StateMachine.context>

--------

where it references the Use Case.

Is there a way to change the context to point to the controller class?

Thanks,

wai yung------- Additional comments from Ludovic Maître Mon Feb 27 10:38:51 -0800 2006 -------

Hi Wai,

To assign an object as the context of an activty diagram i usually do the

following :

- create an use case

- create a class

- create an activity diagram for the use case

- select the activty GRAPH,

- in the property panel use the dropdown list named "Represented Modelelement"

to assign the context of the graph.

Is it what you want to do ?

 ------- Additional comments from Bob Tarling Mon Feb 27 12:11:28 -0800 2006 -------

Is it worth adding context menus to help with this?

Right click on diagram background or explorer element?------- Additional comments from wai yung Tue Feb 28 07:54:39 -0800 2006 -------

Yes. This is exactly what I want.

Thanks------- Additional comments from Ludovic Maître Tue Mar 14 14:07:23 -0800 2006 -------

*** Issue 4090 has been marked as a duplicate of this issue. ***

--------------------------------------------------------------------------------

AndroMDA 3.0 M3--开源的MDA方案即将可用(转帖)

现在的AndroMDA已经出到3.2了,这篇3.0 M3的作为收藏。

 

AndroMDA 3.0 M3--开源的MDA方案即将可用  (转自:http://www.chinaitpower.com/A/2005-03-01/148795.html)

 

作者:未知 时间:2005-03-01 12:12 出处:Blog 责编:chinaitpower 

 

              摘要:暂无

 

 

因为有些IDE不支持,一直没有完整留意UML的扩展机制,所以也就以为UML不很适合做MDA。比如生成Hibernate的hbm文件,一些属性的辅助属性比如lazy-load,应该放在Class图的哪里呢? 最近AndroMDA在TSS上发广告,介绍说AndroMDA 3.0 M3作为正式版前的最后一个MileStone已经推出。就连过去看了一下。原来除了StereoType,UML另有Tagged Value的机制,可以把一些属性附在类的方法和属性上。 AndroMDA的结构应该说比较开放和实际的 1.AndroMDA使用过程 1.程序员通过Poseidon or MagicDraw 绘制UML图并导出XMI 或者使用 Schema2XMI工具从数据库生成XMI 在绘制的过程中需要加入AndroMDA所需的StereoType和Table tag,column Tag等。 MagicDraw似乎比较难看,而Poseidon还提供AndroMDA的plug-in,什么功能还没细看。 2.用户通过Ant运行AndroMDA Ant脚本除了指明xmi文件外,另一个很重要的节点就是节点,指明了Hibernate,Spring所需的一切项目级资料比如生成目录,数据源名称等。 3.AndromMDA解释XMI为相对高层的概念,然后调用Cartridge的Velocity语法模板的生成目标代码文件。 目前提供EJB,Hibernate,Spring等几个Cartridge。 如果要扩展Cartridge,只需要按照文档所教的方法,从内到外进行各种层次的增加,修改和替换。 2.五个核心部件核心部件的设计代表了AndroMDA扩展的野心 1.Template Engines 目前使用Velocity作为模板语言,支持向其他语言的扩展。 2.MetaFascade 提供一个高层的Meta-Data访问API, 支持UML1.3、1.4、2.0等等语法的MOF model并可自行扩展。 3 Repositories 支持从XMI文件中读取MOF model,支持其他格式的扩展。 4.Cartridge 通过MetaFascade读取元模型,通过模板生成代码的核心。AndroMDA自带了Spring,Hibernate等Cartridge,也可自行扩展。 5.Translation-Libraries 把平台无关代码翻译成平台相关代码。比如Hibernate的getXXX()方法的HSQL语句,用者可以选择用Tagged Value写在模型里,也可以选择写成平台无关的OCL查询语言,然后用Query-Translation把它翻译成Hibernate HSQL,日后也可次翻译成EJB的EQL。 目前有Query和Valiations两个Library,亦可自行扩展。 3.AndroMDA的意义 AndroMDA带出的最重要的信息是,相对标准的,开源的MDA方案开始可用了,无数程序员不懈的代码自动生成的分散努力,有望纳入一个比较统一的框架内进行。 对比自己的简易版MDA方案: 1.模型的编写与维护 好处第一是, 以前的模型是自己制定的XML标准,现在是标准的UML语言,谁不想自己的东西标准化一点,谁不想被招安阿。 第二是模型可以使用图形化的工具维护模型了。 坏处也是,只能使用图形化工具维护模型了,没有了以前XML文件的文本级的简单。 2.代码的生成 大家暂时都是使用Velocity,只不过它有现成的Cartridge,估计还会不断增加,众人拾柴,比自己孤军奋战,一些大点的模板根本没法写(从经济学角度)好多了。 坏处就是以后修改扩展模板都要循规蹈矩,依足手续,比原来的随意扩展麻烦好多。 等他的正式版出来, 正好也是我们项目结束, 整理代码以作重用的好日子吧. 

 

ArgoUML的开发者向AndroMDA项目提交Argo与Andro组合的教材

"Tom Morris" <tfmorris@gmail.com>  Add to Address Book  Add Mobile Alert 

To: users@argouml.tigris.org

Date: Sat, 11 Mar 2006 18:45:43 -0500

Subject: [argouml-users] Instructions for using ArgoUML with AndroMDA tutorial

   

I've created a first draft of directions on how to use ArgoUML for the

AndroMDA "Getting started for Java" tutorial and the AndroMDA team has

included them as part of the tutorial.  You can access them from the

AndroMDA home page (http://www.andromda.org) by clicking on the link in

the

Documentation box on the left hand side.

The tutorial requires an AndroMDA 3.2 snapshot (3.2 is still under

development) and it doesn't cover any web stuff (Struts or JSF), but it

does

provide a very detailed step-by-step for those who are new to AndroMDA

and

want to be led through the initial learning phase.

If you find problems or have suggestions on ways to improve the

instructions, please send me mail and I'll get them incorporated.

Tom

UML在关系型数据库设计中的应用(转帖)

UML在关系型数据库设计中的应用 (转自:http://edu.sdinfo.net/74596379271364608/20030822/1194035.shtml)

发布时间: 08月22日 11:34

------------------------------------------------------------------------------------------------------ 1. 介绍

  许多人认为面向对象概念和关系型数据库相互不一致,并且不能结合。事实上完全相反!经过灵活的使用,一个关系型数据库能够为面向对象(OO)模型提供一套优秀的实现。同样的模型能够用来开发编程代码和关系型数据库结构。

  关系型数据库技术是意义深远的、强大的,但它比许多开发商使你相信的要难得多。单个表是简单易懂的、直观的。但由数以百计的表组成(这是常见的)的应用要彻底了解是相当困难的。这正是OO模型有用之处。 OO模型使你深入地、连贯地思考问题。

  OO模型提供一种问题的超结构(superstructure)的思考方式,然后该方式能够用关系型数据库的更低层的组成块来实现。

  本文章综合地讨论了关系型数据库技术,而不是集中于特定的产品上。我们将不讨论物理设计细节(例如存储分配和物理聚集),因为它们是依赖于产品的。

  用关系型数据库实现UML模型有两个方面:映射结构(第2节)和映射功能(第3节)。第4节注解了面向对象到关系型数据库的扩展。第5节总结本文章。

  2. 结构映射到表

  UML对象模型在本质上只是一个扩展的实体-关系(ER)模型 。使用设计数据库的ER模型的方式受到普遍接受,而我们以一种近似的但更强大的方式-使用UML对象模型。OO模型的主要优势在于编程和数据库的相同的模型工作。而且,作为考虑功能性的一种方式(第3节),我们强调OO模型的导航。这一节显示如何实现UML对象模型的主要构造。

  2.1 标识(identity)

  实现对象模型的第一步是处理标识。我们从定义几个术语开始。

  1)候选键(candidate key)是一个或多个属性的组合,它唯一地确定某个表里的记录。一个候选键里的属性集必须是最小化的;除非破坏唯一性,否则属性不能从候选键删除。候选键里的属性不能为空。

  2)主键(primary key)是一个特定地选定的候选键,用来优先地参考记录。

  3)外键(foreign key)是一个候选键的参考。外键必须包括每个要素属性的一个值,或者它必须全部为空。外键用来实现关联和一般化。

  正常地你应该为每个表定义一个主键,尽管偶尔有例外。我们强烈建议所有的外键都只指向主键而不是其它的候选键。

  定义主键有两种基本的方法:

  1)基于存在的标识。你应该为每个类表加一个对象标识符属性,并将它设为主键。每个关联表的主键包括一个或更多的相关类的标识符。基于存在的标识符有作为单独属性的优势,占位小且大小相同。只要你的关系型数据库管理系统(RDBMS)受支持,基于存在的标识符就没有性能的劣势。(多数RDBMS提供有效的基于存在的标识符的分配顺序号码。)唯一的劣势是基于存在的标识符在维护时内没有固有的意义。

  2)基于值的标识。一些真实世界的属性的组合确定了每个对象。基于值的标识有不同的优势。主键对于用户有固有的意义,容易进行调试和数据库维护。在另一面,基于值的主键很难改变。一个主键的改变需要传播到许多外键。一些对象没有自然的真实世界里的标识符。

  我们推荐你在超过30个类的RDBMS应用里使用基于存在的标识。基于存在和基于值的标识都是所有RDBMS应用的可行选项。

  2.2 域(属性类型)

  属性类型是UML术语,对应于数据库著作里的域的术语。比起直接用数据类型,域提升到更一致的设计,并便利了应用的定位。

  简单域很容易实现。你仅仅要定义相应的数据类型和大小。并且每个用了域的属性,你都必须为每个域约束加入一条SQL查询子句。简单域的一些例子是:名字(name),长字符(longString)和电话号码(phone-Number)。

  一个枚举域把一个属性限制在一系列的值里。枚举域比简单域实现起来更复杂,图表1显示了四个方法。

 

图表1:枚举的实现方法

 

  2.3类

  正常情况下,我们把每个类映射为一个表,每个属性映射为一个列。你可能因一个已产生的标识符(基于存在的标识符)、隐藏的关联(第2.4节)和通用鉴别器(第2.5节)需要一些另外的列。

  2.4关联

  现在我们讨论关联的实现。我们已经把我们的陈述分为建议的映射(我们正常使用的映射),可选的映射(我们偶尔使用的映射)和不鼓励的映射(我们遇到的应该避免的错误)。我们所有的例子都采用基于存在的标识。

  2.4.1 建议的映射

  多对多关联。用一个特别的表(图表2)来实现一个多对多关联。关联的主键是每个类的主键的合并。那些省略号(...)表示在模型里没有显示出来的属性。主键用黑体字体显示。

  一对多关联。把一个外键隐藏在“多”表(图表3)。角色名字成为外键属性名字的一部分。

  零或一对一关联。把外键隐藏在“零或一”表(图表4)。

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

 

图表2:建议的实现:特殊的多对多关联表

 

图表3:建议的实现:隐藏的一对多关联

 

图表4:建议的实现:隐藏的零或一对一关联

  可选的映射 正常情况下我们使用建议的映射。但有些偶尔的情况,可选的映射更合适。

  特别的表。你也可以用特别的表(图表5)来实现一对多和一对一关联。特别的表给了你更统一的设计和更大的扩展性。无论如何,特别的关联表打碎了数据库,并增加了表的数量。此外,特别的关联表不能强迫一个更低的多重性限度为“一”。

 

图表5:可选的实现:特别的一对x关联表

  不鼓励的映射 我们已经注意到有些开发者选择有缺陷的映射。我们要注意这些映射以便可以避免。 合并。不要合并多个类,不要把关联强制成为一个单独的表(图表6)。这样减少了表的数量,但会干扰第三范式。

  两次隐藏一对一关联。不要把一个一对一关联隐藏两次,每次隐藏在一个类里(图表7)。这是多余的,无助于性能。

  相同的属性。不要用相同的属性来实现多个关联角色(图表8)。相同的属性使编程复杂,降低了扩展性。 泛化 现在我们讨论泛化。我们这里只论述单个继承。 建议的映射 最简单的方法是只映射超类和每个子类为一个表。所有的表共享一个共同的主键。应用必须执行子类的划分,因为RDBMS支持。(关于后者的详尽的描述,请参阅第4节。)

  特别的表。映射超类和每个子类为一个表(图表9)。所有的表共享一个共同的主键。鉴别器指出每个子类记录的适当的超类表。

 

图表9:建议的实现:分开的超类和子类表

  可选的映射 泛化有几个可选的映射。 消除。你可以优化除去那些除了主键外没有别的属性的类(图表10)。这样减少了表的数量,但提供更少的正规实现。

  减少超类属性。你可以除去超类表并把超类属性复制到每个子类(图表11)。这样可以有描述每个对象为一个表的优势。无论如何,它将引起数据库结构的冗余,你查找一个对象时可能需要搜索多个子类表。

  增加子类属性。作为第三个可选项,你可以除去子类表并存储所有的子类属性到超类表里(图表12)。这样用一个表描述每个对象,但干扰了第二范式。

 

图表10:可选的实现:消除不必的子类表

 

图表11:可选的实现:减少超类属性

  

 

图表12:可选的实现:增加子类属性

 

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

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

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

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

  我们已经简要地论及参考完整性,因为它是个高级话题。参考有更多的解释z和例子。 索引 实现数据库结构的最后的一步是加入索引来调整数据库性能。正常地,你应该为每个主键和候选键定义一个唯一的索引。(多数RDBMS作为SQL主键和候选键约束的副作用来建立唯一的索引。)你也应该为每个被主键或候选键所约束的外键建立一个索引。

  我们强调索引的重要性。外键和主键的索引使在对象模型里能快速地遍历是不容怀疑的。你必须包括这些索引否则你将使用户感到灰心。你应该在你的数据库开始设计阶段里加入索引,因为它们很容易加入并且也没有什么好理由推迟加入。

  数据库管理员(DBA)可能为经常请求的查询定义了额外的索引。DBA也可能采用产品相关的调整性能的机制。 范式 范式是关系型数据库设计的提高数据一致性的有效方法。我们的书3讨论了范式,但我们关于这个问题却言过甚微。我们将利用这篇文章的机会来澄清我们的观点。如果你不熟悉范式你可以跳过这节。我们的说明是针对关系型设计人员,他们正在尝试用面向对象适应他们原有的技能。

  范式是正确设计关系型数据库的精确的原则。同样地,它们与使用了什么开发技术是无关的 - 基于属性的设计、基于实体的设计、面向对象设计或其它什么。 过去使用基于属性设计的方法,开发人员不得不非常注意范式;范式提供了分组数据的根据。相反地,范式对于基于面向对象(或基于实体)的开发不是很重要。如果你采用OO方法并且你的模型经过很好的构思,那你就正在把数据组织成为有意义的单位,也在本质上满足了范式的规定。如果你愿意,你仍能够检查范式,但这样的检查是不必要的。 摘要 图表13总结了我们已经陈述的映射规则。这些映射规则的完整例子,包括一个UML对象模型,能够在这篇完整的扩展版本里找到(Adobe Acrobat PDF文件)。

 

图表13:推荐的映射规则的摘要

  

  把功能映射到SQL命令 对象模型为数据库应用提供三种主要的用途。 结构。对象模型指明数据库结构。我们已经在第二节探讨了这个方面。

  约束。对象模型也指明了能存储的数据上的重要的约束。相匹配的实现必须为迎合这些约束而努力。我们的映射规则的处理方法以及第二节里的参考完整性指出了许多约束。(本文没有论及的另外的UML构造,能获取更多的约束。)

  潜在估算。一个对象模型指明潜在估算;它是关于引起哪些查询和如何公式化的蓝图。第三节将简要地阐明第三个目的。

  对象模型不仅仅是被动的数据结构,相反它们能够帮助你思考一个应用的功能。你可以根据遍历一个对象模型说出它的许多功能。例如,根据我们对一个模型检查用例时的遍历,我们进行思索。这强调对象模型的估算能力对于RDBMS应用是特别重要的,因为遍历表达式可以直接映射到SQL代码。

  UML对象约束语言(Object Constraint Language,OCL)有助于表达遍历。点符号导航从对象到对象和对象到属性。方括号表示对象集合的过滤器。我们加入冒号(:)操作符来表示泛化的遍历;因为我们正常地用多个表来实现一个泛化继承,清楚的遍历很有用。

  图表14里的遍历表达式例子是基于我们创建的UML对象模型上的(请参阅本文的扩展版本(Adobe Acrobat PDF文件)),我们把它们映射为SQL代码。我们用冒号开始SQL编程变量。

 

图表14:对象模型遍历和SQL代码的例子

  到RDBMS的OO扩展 数据库团体对RDBMS的OO扩展有兴趣。产品和SQL标准正尝试加入到OO扩展里。我们将简要地陈述一下这个技术的方向。 抽象数据类型(ADT)。这是个好主意,扩展RDBMS的能力。开发商为这个技术使用了许多名字,例如Oracle cartridge和Informix data blades。ADT的缺点是它们把你紧紧绑在特定的一个开发商上;ADT的范畴超越了SQL标准。因此,你应该只在ADT的好处很明显的时候才使用。

  在关于ADT如何适合数据库开发的著作里有一些混乱。如果你使用OMT开发过程,你能够用属性实现简单域,用ADT实现复杂域。你仍应该用表实现类。 SQL3指针。最新的SQL标准的版本,SQL3,加入了作为一种数据类型的指针符号。显然,其意图是支持导航和面向对象。我们对于SQL3指针最友善的评语是,它们是嫁接的,是可以忽略的。更深入的批评是,指针在理论上是荒谬的,增加了复杂性,又没有扩展SQL的表达能力。CJ Date在上次的九月对象/关系型会议上雄辩地讨论了这一点。

  好了,那么我们冷淡地对待抽象数据类型和SQL指针的指责。但我们相当喜欢面向对象技术和关系型数据库。有两个为RDBMS的扩展可以使它们更容易用于OO技术。我们将很乐意看到RDBMS开发商把这些能力加入到他们的产品中。 扩展的参考完整性动作来支持泛化。当前的参考完整性机制是单向的。为了完全支持泛化,我们需要一个双向的机制。这样,一条超类记录就可以依赖一条子类记录。并且,一条子类记录就可以依赖一条超类记录。我们通过例子可以最好地解释这点。

  图表15摘录于我们的在3的财务案例学习。我们用资产超类来统一某些没有显示在摘录里的通用的数据和功能。一项资产可以是一只股票或股票特权。一只股票可以有许多它的股票特权。例如,IBM股票可以有许多达到价格和过期日期的写下的放或叫特权。

 

图表15:参考完整性和泛化的例子

  我们推荐的泛化实现是特别的表 - 映射该超类和每个子类为一个表。然后,我们就可以使用参考完整性使股票特权和股票的记录依赖于资产。一个资产记录的删除级联到相应的子类记录、股票特权或股票的删除上。我们也能够定义一个参考完整性动作,这样一个股票的删除就级联到关联的股票特权记录的删除。

  现在问题如下。如果我们删除的一项资产是一只股票,资产记录的删除级联到引起股票记录的删除。随后,股票记录的删除级联引起所有股票特权记录的删除。但现在参考完整性使我们失败了:一个股票特权记录的删除并不引起一项资产记录的删除。删除级联只能从超类走到子类。为了完全的行为,级联应该双向地走下去。

  当前有用的参考完整性的工作是做更多的编程(也即做更多的工作和风险更多故障)。在我们的用例学习的实现里,用户随时要删除一项是股票的资产,我们不得不书写额外的代码来首先检查关联股票特权的存在性,然后删除它们。 支持交叉表的记录划分。单独继承(泛化的最常见方式)的含义是一个超类的每个实例都是用多数只有一个子类来例示。现在的RDBMS不能容易地加强这个约束。例如,没有什么防止下面的情形。一只股票可以用ID18加入到资产表,用ID18加入到股票表,并且也可以用ID18加入到股票特权表。再一次地,我们为了确信行为的完整,不得不作额外的编程,而不是写一个简单的声明的约束 

  结论

  本文陈述了用关系型数据库实现UML模型的快速的概观。我们希望本文向你演示的技术是足够适宜的。一个训练有素的开发人员能够用关系型数据库准备一套优秀的OO模型的实现。如果你要关于实现机制的更多的细节,参考3有另外的信息,并且也覆盖了我们没有在这里讨论的一些高级模型建模结构。

文章出处:《中国电脑教育报》

记录一个好像还不错的uml模型到代码的code generator (AndroMDA

  一直知道ArgoUML在进行与androMDA的配套工作,昨天第一次上这个AndroMDA浏览了一下。好像还不错,以后可以实践一下。

  下面是它的定义:

What is AndroMDA?       

AndroMDA (pronounced "Andromeda") is an extensible generator framework that adheres to the Model Driven Architecture (MDA) paradigm. Models from UML tools will be transformed into deployable components for your favorite platform (J2EE, Spring, .NET). Unlike other MDA toolkits, AndroMDA comes with a host of ready-made cartridges that target today's development toolkits like Axis, jBPM, Struts, JSF, Spring and Hibernate. AndroMDA also contains a toolkit for building your own cartridges or customize existing ones - the meta cartridge. Using it, you can build a custom code generator using your favorite UML tool. 

  

Core Features       

AndroMDA currently comes with the following features:

Modular design: all major building blocks of AndroMDA are pluggable and can be exchanged to meet your needs

Support for major UML tools like MagicDraw, Poseidon, Enterprise Architect and more

Comes with the complete UML 1.4 metamodel (support for UML 2.0 is currently being developed) - alternatively, you can bring your own metamodel in MOF XMI and generate code from models based on it

Validates the input models using OCL constraints which are related to the metamodel classes. Comes with pre-configured constraints that protect you against the most common modeling mistakes - add your own project-specific constraints, too.

Model-to-model transformations help to raise abstraction level. Write your own transformations, currently in Java, or in any transformation language, e.g. the QVT-like Atlas Transformation Language (ATL), in the next major AndroMDA release.

Can generate any kind of text output using templates (source code, database scripts, web pages, O/R mapping configuration files, etc.) -  you teach it, AndroMDA does it!

Templates are based on well-known template engines. Currently, Velocity and FreeMarker are supported

Ready-to-use cartridges for common enterprise architectures (EJB, Spring, Hibernate, Struts, JSF, Axis, jBPM)

Support around the clock by team members around the globe: Measure the response time for questions in forum.andromda.org and be amazed by it! The forum already contains more than 10.000 articles.

 

  

Cartridges       

Very much like Eclipse, AndroMDA features a plug-in architecture. AndroMDA itself basically is a transformation engine. To support arbitrary target architectures, you can plug-in custom transformations. These transformations are packaged as so-called cartridges.

AndroMDA comes with a host of ready-to-use cartridges such as:

Spring

EJB 2 / 3

Webservices

Hibernate

Struts

JSF

Java

XSD

You can also write your own cartridge to support your own architecture or framework. AndroMDA can produce output for any architecture and computer language you might imagine. Courses for cartridge writing are available at AndroMDA.com.

 

 

 

反映给argouml的三个bug不能在0.20版本解决

  今天下午,花了1个小时收邮件,主要看了这段时间积累的argouml邮件列表里的邮件,其中三封邮件告知我提交的三个bug没有在0.20版本中得到解决。看来,argouml小组目前着重在argouml基础构架的改革,而对这些应用性的问题还没有来得及去做。这三个问题分别是:

1、  [Issue 3836] Wrong fill color for states  Sat Jan 28, 2006 2k

http://argouml.tigris.org/issues/show_bug.cgi?id=3836

2、 [Issue 3777] import description is error in an ArgoUML generated *.java file  Sat Jan 28, 2006 2k

http://argouml.tigris.org/issues/show_bug.cgi?id=3777

3、 [Issue 3356] Multiplicity not preserved in roundtrip engineering 

http://argouml.tigris.org/issues/show_bug.cgi?id=3356

(转帖)设计已死? 预先设计 Vs. 持续设计

(转自:http://www.matrix.org.cn/resource/news/463_Up+Front+vs+Continuous.html)

设计已死? 预先设计 Vs. 持续设计

chris 发表于2006-01-18

作者:chris 来自:matrix

评论数:13 点击数:775

摘要:

在很多刚开始接触XP的人看来,XP仿佛给软件设计判了死刑!在XP中,软件设计不仅被讥笑为"Big Up Front Design"。甚至一些软件设计技术,比如UML(统一建模语言)、灵活框架技术、模板设计等似乎都不那么重要了。 文章工具

收藏

发表评论

复制链接

在很多刚开始接触XP的人看来,XP仿佛给软件设计判了死刑!

在XP中,软件设计不仅被讥笑为"Big Up Front Design"。甚至一些软件设计技术,比如UML(统一建模语言)、灵活框架技术、模板设计等似乎都不那么重要了。

up-front design,也就是预先设计,需要提前考虑软件的整体需求,甚至必须预测到开发过程中软件需求发生的变化,这往往是很困难的。因为处理变更需求的方式之一是做灵活的设计,以便当需求有所变动时,你就可以轻易的变更设计。然而,这需要你对将要发生的变动有深刻的洞察力。甚至很多人开始专注于研究需求工程过程(requirements engineering processes),希望得到更准确的需求以避免后面对设计的修改。但是即使朝这个方向去做一样无法解决问题。很多无法预知的需求变更起因于业务的变化。这是不能避免的。

而持续设计则完全相反。

通过不断迭代,持续设计可以在迭代过程中不断演进,从而适合新的需求。XP中有许多启动实践,其中最重要的是测试(Testing)和持续集成(Continuous Integration)。

然而,演进式设计可能因为特定的设计策略(ad hoc design decisions)和照成软件开发混乱而行不通,进入恶梦般的"code and fix"。所以,持续设计也被很多人讥笑,说这是"黑客式开发"。

关于,预先设计 和  持续设计,你有什么看法呢? 正在使用XP的人,发表下见解吧!

本页面地址:  

→用户评论列表

#7832 评论作者: littlebat 发表时间:2006-01-20 10:40

  不懂xp,也不懂设计,只知中国有“中庸”一词很有道理。我觉得我们征对任何一件事要寻求适合这件事的平衡点。

#7819 评论作者: softtiger 发表时间:2006-01-19 10:46

在我看来,当项目具有一定的复杂度时,结论就非常明显了。象一般的应用,由于采用了现成的框架,设计工作很小(业务上的调查还是不能避免的);对于嵌入式平台的开发,若没有一个相对较长的预研工作,二周左右的初始迭代只能是个笑话。总而言之,要视项目的具体情况,灵活采用相应的开发过程。

#7796 评论作者: cleverpig 发表时间:2006-01-19 09:02

to li_nummereins:

完全同意你的见解。

#7786 评论作者: matrix_victor 发表时间:2006-01-18 04:45

有一定道理,不过预先设计还是很重要的。不过个人觉得预先设计可以尽可能做好,在实际进行中不断改进,也算是持续设计了。在此期间文档就没必要那么详细八股了,以协作人员方便交流为原则,等系统测试完成后在形成最后的文档,这样比较好

#7785 评论作者: li_nummereins 发表时间:2006-01-18 03:18

对待“过渡设计”,我们必须在初始设计阶段就做好沟通,做到需求驱动设计。这点是最最重要的。可往往很多项目都力争马上编码,这样做非常错误。我反对在具体技术实现上耍“学术”。只要是能够使用户满意,开发顺利的技术就是好技术。我们的目的是解决问题,而不是制造问题。

#7784 评论作者: topreap 发表时间:2006-01-18 02:41

可以讨论一下“过度设计”的问题,预先设计如果是过度设计往往导致项目延期。。。。但如何避免过度设计关系到管理上的问题,特别是项目经理的管理能力、经验。。。。。

#7782 评论作者: goodsuperstar 发表时间:2006-01-18 02:05

预先设计总是有必要的

首先对整体有个大致的了解,明确方向,起着纲举目张的作用

但是现在很多预先设计已经走向极端,将一些后期考虑的细节问题过多的放到预先设计中,造成整个项目工期延误。

#7781 评论作者: usherlight 发表时间:2006-01-18 12:55

我还是认为预先是重要而且必要的.

否则后期的改动难以进行.

#7780 评论作者: ginger547 发表时间:2006-01-18 12:32

我非常的同意 持续设计的做法!我也很欣赏 write test first ,write code second ,then refactor!

#7779 评论作者: tcmak 发表时间:2006-01-18 11:33

其實 XP 或者 Agile 等方法, 其重點在於減少 "浪費", 此話其實也很 "禪", 像大道理多於執行手則, XP, 及其他敏捷開發界的人士都常說不要把這些東西當成為必然, Design 是要做的, XP 或者其他敏捷開發方法也沒說不要做任何設計工作, 但是, 我們最不想看到的就是花太多時間去做什麼 UML, Data-flow diagram... 或者其他 "浪費" 的事情.

什麼是 "浪費" 呢? 就是對客人沒用的東西, code 對客人有用, 因為有了 code 系統才會行, 但是一個 data-flow diagram 對客人又有多少價值呢? 敏捷開發中沒有反對做什麼 diagram, 只要有用就可以了. 而且重點是, 就算要做什麼 diagram 都好, 都不用把他們做的像什麼嚴謹的文件, 在白板上手畫的已經很 "足夠" 呢

如果管理層或者客戶真的要什麼嚴謹的文件, 就盡量用 program generate 出來呢.

再者, 敏捷開發也講求 Refactoring, 不是要做少一點 design, 但 Refactoring 也是面對避免不了的改變其一個 "適應" 方法, 使到 code 可以更易維持, 系統亦更易理解

XP界其中Ron Jefferies 其中一文講及 Design:

http://www.xprogramming.com/xpmag/whatisxp.htm#design

Design 在 XP 中也有重要地位, 而且是以不段改善和進化的形式去體現, 如果就設計己死, 那我認為是 "Big Up Front Design is Dead".

XP 或者所有敏捷開發都很講求 "紀律", Coding Standard 是其中一重 "紀律" 的體現, 他們也對 testing 有很高的要求的呢 (上文也有提到測試的要求), 而絕不是黑客式開發. 短的開發週期就是希望不要讓隊伍陷入 "Analysis Paralysis"

最後... "Big Upfront design" 所帶出的主要問題是如何減少在開發過程中的 "浪費", 什麼才是 "足夠", 對客人有 "價值", 如何可以迅速地 "適應" 轉變, 只要掌握到, 那你自己也可以有一套自己敏捷的方法.

另外, 如果還是對 "Big Upfront Design" 念念不忘, 又或者 XP 那樣感覺還是不太舒服, 可以看看以下文章, 提及的 design 比 XP 多, 我想也比較易讓大家理解.

http://www.agilemodeling.com/essays/amdd.htm

(不好意思, 兩篇文章都未有中文版)

#7778 评论作者: icess 发表时间:2006-01-18 11:16

January 15, 2006

Continuous Design

Continuous design, also often called evolutionary design or emergent design, is an alternative to up-front design of software. Traditional up-front design (Big Up-front Design, as extreme programming labels it) involves anticipating the requirements of the software, and even more difficult, how the software's requirements will change over time. Then, based on these assumptions, a design or architecture is put in place that allows developers to efficiently implement the needed functionality in a way that leaves the software open to the anticipated later changes.

Continuous design takes a different approach.

By using an iterative, agile approach to software development, the design of an application's code can evolve over time instead of being specified up-front before development begins. In continuous design, one always designs just for the current iteration's required feature set. Code the new features, then refactor away any code smells. If a new feature cannot be implemented because of the existing design's limitations, then refactor the design into something that will accommodate the new feature. But, stop there! By avoiding the temptation to design for anticipated future change, one keeps unnecessary complexity out of the system. How often have you designed the use of a strategy pattern to accommodate an imaginary need to swap out implementations of a particular interface? But the multiple implementations never materialize.

来源:http://java.about.com/b/a/235746.htm

#7774 评论作者: jslzl 发表时间:2006-01-18 09:12

楼主的疑惑可以理解,计算机的技术和手段日新月异,面对这些技术,甚至名词,让

人有时不知如何下手。就开发流程来说,有传统的rup过程,xp等。但是bob (Expert One-on-One J2EE Development develop without Ejb 和Spring的作者)的一句话倒是让我深刻:寻证方法也就是说我们应该根据我的项目的经验去寻找更好,更快的解决方法,如何天天琢磨别人的思想,呵呵,很累的。所以我常说“去你的,大师”。其实那些所谓的大师在能够提出些思想方法,不过是在反复总结自己和别人罢了。

所以,楼主要是愿意比较xp和传统rup等,应该至少先使用一种开发过程,并深刻理解,然后才能对比吧。对我而言,开发过程两种方法同时都在使用,怎么快就怎么来吧!

一席废话,呵呵。欢迎拍我

#7773 评论作者: li_nummereins 发表时间:2006-01-18 09:11

预先设计及其重要。这就像打天下,开始必须要有明确的纲领,将主要矛盾突出。这个阶段不能关注细节,要站在战略的高度思考问题。设计以方向性的概要设计为主,以主要、现存的、明显的需求驱动设计。持续设计专著细节,但对待已经存在好的预先设计必须采取迭代式补充,并充分利用绩效,挣值等方法不断进行校验。要知道,欲望是无限的,资源是有限的。要干好一个项目,最主要的是知道那些必须作,哪些决不能做。

(转帖)开发一个dvd play er系统,用例到底应该如何划分呢

转自:umlchina yahoo讨论组

  To: UMLChina@yahoogroups.com

From: "赵鹏" <zhaopeng@webservice.com.cn>  Add to Address Book  Add Mobile Alert 

Date: Fri, 13 Jan 2006 12:49:01 +0800

Subject: 答复: 回复: [UMLChina] 开发一个dvd play er系统,用例到底应该如何划分呢

   

一般而言,一个用例就是参与者的一个目标,它是一个可观察到、可度量的过程。

对于参与者是一个在有限时间内可完成的一个过程。

如“播放碟片”,从不同角度看,就会有不同的解释。

从功能看,就是播放机上的一个按钮,是播放机的一个功能。

从目标看,对参与者是一个完整的过程,它包含一些列的功能(其中包括上面的功能),它是参与者的一个意图。

如果把“播放碟片”写成用例可能像如下的例子

 

播放碟片(仅作示例)

参与者:想看碟子的人

前置条件:播放机已经接通电源。

主要场景:

1、参与者打开播放机电源。

2、播放机点亮电源指示灯。

3、参与者打开碟片舱门。

4、播放机弹出舱门,指示灯闪烁。

5、参与者关闭舱门。

6、播放机确认舱门正确关闭,并确认碟片可以播放,显示碟片时间。

7、参与者播放碟片。

8、播放机按照碟片预设的流程播放。

扩展

3a、如果参与者连续发出关闭和打开舱门命令,播放机近当舱门打开后才接受最后一条指令。

3b、如果参与者发出其它指令,播放机将忽略。

5a、如果参与者连续发出关闭和打开舱门命令,播放机近当舱门关闭后才接受最后一条指令。

5b、如果参与者发出其它指令,播放机将忽略。

6a、碟片不可识别,播放机弹出碟片。

8a、参与者可以随时中止播放。

 

相关的用例可能还会包括:

一、用户从指定时间处开始播放。

二、用户回看播过的内容。

。。。。。。。

 

从上面的用例可以看到“播放碟片”即出现在用例这个层次,也出现在具体功能这个层次(本人觉得应该避免这种名次的混淆,此处仅作为示例)。

从指这样的用例可以分析和提炼出,一个播放机具体需要具有哪些系统特性,即可以得到一个功能列表,如你在问题中所提到的。

系统特性,可以用“系统可以做....”这样的语句来验证。

如,播放机可以播放碟片、播放机可以调到指定时间、播放机可以快进.............

 

 

--------------------------------------------------------------------------------

赵鹏

软件开发部

上海星移软件有限公司

MSN:dearzp@hotmail.com

Email:zhaopeng@webservice.com.cn

Biz Tel:021-54395480

more for www.webservice.com.cn

 

--------------------------------------------------------------------------------

发件人: UMLChina@yahoogroups.com [mailto:UMLChina@yahoogroups.com] 代表 周

发送时间: 2006年1月13日 12:15

收件人: UMLChina@yahoogroups.com

主题: 回复: [UMLChina] 开发一个dvd player系统,用例到底应该如何划分呢

 

如果说快进快退实现了用户定位影片的目的,可以作为单独的用例,那类似于“下一曲”“上一曲”以及搜索查找都可以做为单独的用例吗?

weijie xu <iam_xuwj@yahoo.com.cn> 写道: 用例的粒度大小是否合适,主要还是要看这个用例是否已经实现了对用户有价值的结果,或者实现了用户的某一个有价值的目标。对于"停止播放"来说,用户的真正目的并不是仅仅用DVD播放软件来停止播放DVD,停止播放单独存在对用户而言毫无意义,只能是作为播放DVD过程中的一个步骤。所以“停止播放”不能作为一个单独的用例,只能作为“播放DVD”这个用例中的一个步骤,并且是最后一步。“快进快退”则不同,它的存在对用户而言是有意义的,它实现了用户定位影片的目的,可以作为一个单独的用例存在。而“选时播放”则是一个比较特殊的播放用例,可以将“播放DVD”include进来,以实现重用和简化的目的。

 

一家之言,仅供参考。

iadomcn <iadomcn@yahoo.com.cn> 写道:

对于用例粒度的选择有点疑惑,

用户作为主要的参与者,以"播放DVD"作为用例,

如果仅仅只是这个用例似乎又包含太多的东西,如"停止播放","快进快退""

选时播放"等等,还是这些都可以单独作为用例呢

那样是不是又将用例划分的太小呢,用例之间的 关系将变得复杂起来

请教 到底应该怎样来划分用例呢

(转帖)《UML:Java程序员指南》的读书笔记

转自:http://www.uml.org.cn/UMLApplication/200509273.htm

 UML软件工程组织     北京火龙果软件工程技术中心

 

--------------------------------------------------------------------------------

《UML:Java程序员指南》的读书笔记

来自:http://blog.csdn.net

1.  第一章 针对Java程序员的UML概述

    1.  UML(统一建模语言)的三个层次:

        1.  概念层(Conceptual)

            接近人类自然语言

            有歧义

            无严格的格式

          

        2.  规格说明层(Specification) 

        3.  实现层(Implementation)   

             规格说明层和实现层接近代码、无歧义、有严格的格式

                                           

    2.  UML分三类:

        1.  静态图(static diagrams)

            描绘类、对象、数据结构以及存在于它们之间的逻辑关系。

      

        2.  动态图(dynamic diagrams)

            描绘运行期间,软件执行流程和软件实体状态改变的方式。

      

        3.  物理图(physical diagrams)

            描绘物理实体,如:源文件、库文件、字节文件、数据文件等,以及它们之间存在的逻辑关系。

          

    3.  类图(静态图)

        1.  长方形表示类,箭头表示关系。

        2.  图中的所有关系叫关联(associatons),关联的命名对应引用的对象的变量名称。

      

    4.  对象图(动态图)

        可以看成是内存的一个快照,主要反应程序中的对象在运行期的信息。

        1.  对象名称有下划线。冒号后面跟着对象类型的名称。

      

        2.  对象之间的关系叫链接(links),链接的命名同样对应引用的对象的变量名称。

      

    5.  序列图(动态图)

        几个术语:

        1.  监护(guards)

      

        2.  构造(construction)

      

        3.  数据标记(data token)

      

        4.  活动(activation)

      

    6.  协作图(动态图)

        序列数的点结构

      

    7.  协作图和序列图的异同点

        同:它们包含的信息相同

        异:协作图描述对象之间的关系,序列图描述消息被执行的前后顺序。

      

    8.  状态图(动态图)

        限定状态机(finate state machines)

        图中的箭头被称为转换(transitions)

  

2.  第二章 使用图

    1.  为何要制作模型?

        制作模型的目的是为了证明模型是否可以正常工作。

        一个模型必须有一个可用的检验标准。

      

    2.  使用UML的时机:

        1.  需要通过检验来确定某些东西是否可用的时候。

        2.  使用UML来检验比用编码来检验更划算的时候。

      

    3.  有效的使用UML

        1.  使用UML在开发人员之间传达设计概念。

            使用UML创建具体算法对应的图,并不方便。

            UML对创建大型软件结构的“路线图”,比较有用。

            通过UML图可以清楚的发现类与类之间的依赖关系和整个系统的结构。

          

        2.  保留和舍弃

            大多数的UML图都是短命的,应该舍弃的。只需记录在白板或白纸上。

            但下列图应该保存下来:

            1.  表现系统中一个通用设计的解决方案的UML图。

            2.  记录了复杂的协议,难以通过代码了解的UML图。

            3.  提供了较少涉及到系统范围内的“路线图”的UML图。

            4.  比代码更易表述设计意图的UML图。

          

            这些保存下来的UML图,应该经过多次迭代精化修改,最终版本应保存在团队都能访问的公共区域。

            长期保存与临时创建的UML图应该分开存放。

      

        3.  迭代精化

            先研究动态场景,然后确定静态结构的内在含义。

            对动态图(如:协作图)和静态图(如:类图)进行多次迭代并不断完善。

          

      

    4.  最适合创建文档的时机:

        团队完成了所有工作,项目即将结束的时候。

      

    5.  使用Interface实现事件机制,避免了button对Dialler的依赖。

        这样按下按键之后可以拨号,也可以做别的事。

      

    6.  适配器

        适配器也叫转接器,用于在一件或多件仪器的不同部件之间实现有效兼容性的装置。

        适配器的作用:实现接口,转发消息。

      

    7.  画UML图时应时刻想像着如何转化为代码。

  

    8.  UML图的目标并不是要如何正确,而是要讨论它的人都理解它,所以UML图应尽量简洁。

      

    9.  什么时候画UML图:

        1.  多人参与开发,且这些人需要理解一个系统的特定部分的设计结构时,开始画UML图。

            所有人都声明已经理解了的时候,停止画UML图。

          

        2.  两个或多人之间对某个设计点产生意见分歧,进行讨论时,需要画UML图。

            讨论完毕,做出决定后,停止画UML图。

          

        3.  思考一个设计时,画UML图会有所帮助。

            思考成熟并完成相应的代码后,停止画UML图。

          

        4.  向他人或自己解释一段代码的逻辑结构时,开始画UML图。

            发觉看代码能理解的更清楚时,停止画UML图。

          

        5.  当项目快要结束,客户需要UML图和文档时,开始画UML图。

      

    10. 什么时候停止画UML图:

        1.  画图并不是一个必经的过程。

        2.  好的设计者只有在需要的时候才编码和画UML图。

        3.  不要在编码之前的设计阶段,去为创建全面的文档而画UML图,这是浪费时间。

        4.  不要为了其他人编码而去画图。

      

    11. UML Case工具:

        1.  UML Case 工具的弊:

            1.  正版价格贵

          

            2.  需要学习周期

      

        2.  自动绘制UML图的协作系统,应当在手动协作系统不够用的时候才去考虑它。

      

        3.  项目中使用UML Case工具或集成于IDE的UML Case工具,应先进行效能实验,三思而后行。

      

    12. 文档

        必须建立文档,但必须谨慎地创建文档。

        软件文档应该言简意赅

        一个软件文档的价值通常与文档的大小成反比。

        wiki是一个团队中协作编写文档的不错方法。

      

3.  第三章 类图

    1.  类图描绘类本身的信息,以及类之间的关系。

  

    2.  类使用正方形表示

        "-"表示私有(private),"+"表示公有(public),"#"表示受保护(protected)

        Figure UML-5-2-1

       

        Figure UML-5-2-1 对应的代码

        public class Dialler

        {

            private Vector digits;

            int nDigits;

            public void digit(int n);

            protected boolean recordDigit(int n);

        };

      

    3.  关联

        大多数情况下是表示对象实例持有着对其它对象的引用。

        Figure UML-5-3-1

       

        Figure UML-5-3-1 对应的代码

        public class Phone

        {

            private Button itsButtons[15];

        };

      

    4.  多重性

        Figure UML-5-4-1

       

        Figure UML-5-4-1 对应的代码

        public class Phonebook

        {

            private Vector itsPnos;

        };

      

        "*"表示数量非常多,所以PhoneBook的成员变量itsPnos的类型往往使用Vector、List或其它容器。

      

    5.  继承

        约定:为了便于区分,通常用垂直方向的箭头表示继承关系,用水平方向的箭头表示关联。

        在UML中,继承箭头指在基类上。

        Figure UML-5-5-1

       

      

        Figure UML-5-5-1 对应的代码

        public class Employee

        {

            ...

        };

      

        public class SalariedEmployee extends Employee

        {

            ...

        };

      

        虚线继承箭头表示实现一个接口。

        虚线继承箭头指向被实现的接口。

        白板上画虚线耗时,可以马虎一下用实线代替。

        Figure UML-5-5-2

       

        Figure UML-5-5-2 对应的代码

        interface ButtonListener

        {

            ...

        };

  

        public class ButtonDiallerAdapter implements ButtonListener

        {

            ...

        };

      

      

        另外一种表示实现接口的方法:

        Figure UML-5-5-3

       

    6.  在一个UML图中,同时展现所有的方法会引起混乱,所以,只提供一批有代表性的方法会使UML图更清晰。

  

    7.  细节

        细节和修饰符大多数时候并不需要,但是有时候它们是很有用的。

        1.  类的构造型

            类的构造型显示在一对双角括号之间,放在类的名称上访。

          

            Java有两种标准的构造型:

            1.  interface

                interface的所有成员函数都是抽象的

          

            2.  utility(工具类)

                utility的所有成员变量和成员函数都是静态的。

              

            类的构造型可以自己定义,但必须所有阅读UML图的人都明白其含义。

          

        2.  抽象类、抽象方法

            用斜体字或用{abstract}属性,表示一个抽象类或一个抽象方法。

            Figure UML-5-7-2-1

           

            Figure UML-5-7-2-1 对应的代码

            public abstract class Shape

            {

                private  Point itsAnchorPoint;

                public abstract void draw();

            };

          

        3.  属性

            1.  属性不是类的一部分,但可用来代表额外的信息。

                属性可被自定义。

          

            2.  属性的形式:用逗号分隔,由名称、值对组成的列表。

                如:{author=Matin,date=20020429,file=shape.java,private}

          

            3.  一个属性的默认值是true,所以{abstract}等价于{abstract=true}

          

            4.  属性被写在类名称的下方。

          

            5.  一个非正式的约定:在白板上{abstract}可以简写成{A}

          

            6.  一般只使用{abstract}属性。

              

        4.  聚合(Aggregation)

            聚合是关联的一种特殊形式,表示一种整体/部分(whole/part)的关系。

            为了防止混淆,应避免使用聚合

            Figure UML-5-7-4-1

           

            Figure UML-5-7-4-1 对应的代码

            public class Whole

            {

                private Part itsPart;

            };

          

        5.  组合(Composition)

            组合是一种特殊的聚合形式

            组合用的极少

            涉及到一个深度复制的问题。

            Figure UML-5-7-5-1

           

            Figure UML-5-7-5-1 对应的代码

            public class Owner

            {

                private Ward itsWard;

            };

          

        6.  多重性(multipicity)

            对象能够持有其它对象的数组或向量,或者说它们能够持有许多同一类型但不同实例的对象。

          

            多重性的表达式:

            数字        精确的数量,使用数组作为容器。

            *或0..*     0个或0个到无数个,使用Vector作为容器

            0..1        0个或1个,在Java中通常用一个空的引用来实现。

            1..*        1个到无数个,使用Vector作为容器

            3..5        3个到5个,使用数组作容器

            0,2..5,9..* 非法的表达式

          

            Figure UML-5-7-6-1

           

            Figure UML-5-7-6-1 对应的代码

            public class BinaryTreeNode

            {

                private BinaryTreeNode leftNode;

                private BinaryTreeNode rightNode;

            };

          

        7.  关联的构造型

            1.  < >     标准UML标记

                源对象创建了目标对象,然后将目标对象传递给系统的其它对象。

                这种关联可应用于工厂模式。

                Figure UML-5-7-7-1

               

                Figure UML-5-7-7-1 对应的代码

                public class A

                {

                    public B makeB()

                    {

                        return new B();

                    }

                };

              

            2.  < >       标准UML标记

                源对象的成员函数中创建了一个目标对象的实例,把这个实例当做一个本地变量。

                Figure UML-5-7-7-2 同 Figure UML-5-7-7-1 ,图中关联的构造型改为< >

               

                Figure UML-5-7-7-2 对应的代码

                public class A

                {

                    public void f()

                    {

                        B b=new B();

                        //use b

                    }

                };

              

            3.  < >   标准UML标记

                源对象的成员函数把目标对象的实例作为参数使用,源对象不保存目标对象的实例。

                Figure UML-5-7-7-3 同 Figure UML-5-7-7-1 ,图中关联的构造型改为< >

               

                Figure UML-5-7-7-3 对应的代码

                public class A

                {

                    public void f(B b)

                    {

                        //use b

                    } 

                };

          

            4.  < >   非标准UML标记

                源对象传递目标对象的一个成员函数时,用到< >

                < >可应用于多种涉及模式,如:Proxy、DECORATOR和COMPOSITE7。

                Figure UML-5-7-7-4  同 Figure UML-5-7-7-1 ,图中关联的构造型改为< >

              

                Figure UML-5-7-7-4 对应的代码

                public class A

                {

                    private B itsB;

                    public void f()

                    {

                        itsB.f();

                    }

                };

              

        8.  内部类

            Figure UML-5-7-8-1

           

            Figure UML-5-7-8-1 对应的代码

            public class A{

                private class B{

                    ...

                }

            };

          

        9.  匿名内部类

            UML还未对匿名内部类提供官方支持

            一种非官方的表示方法,用有一个< >构造型的嵌入类来表示。

          

            Figure UML-5-7-9-1

           

            Figure UML-5-7-9-1 对应的代码

            public class Window

            {

                public void f()

                {

                    ActionListener l = new ActionListener()

                    {

                        //implementation

                    };

                }

            };

          

          

        10. 关联类

            关联类能进一步的展示一个特殊的关联如何被实现。

            比如:对于多重性关联使用何种容器

          

            Figure UML-5-7-10-1

           

            Figure UML-5-7-10-1 对应的代码

            public class Address

            {

                private Vector itsLines;

            };

          

            关联类能够指明的特定形式的引用有

            1.  不固定的引用(WeakReference )

            2.  松散的引用(SoftReference)

            3.  幻影的引用(PhantomReference)

          

            Java 2 引用类使用指南-学习如何有效地使用 SoftReference、WeakReference 和 PhantomReference

            http://www-900.ibm.com/developerWorks/cn/java/j-refs/index.shtml

          

          

        11. 关联限定符

            源对象通过某种类型的关键字或标记与目标对象实例发生对应关联时,使用关联限定符。

            Figure UML-5-7-11-1

           

            Figure UML-5-7-11-1 对应的代码

            public class LoginServlet

            {

                private String empid;

                public String getName()

                {

                    Employee e = DB.getName(empid);

                    return e.getName();

                }

            };

          

            关联限定符使用较少

          

        12. 少用UML远比多用UML好。

4.  第四章  序列图(sequence diagram)  动态图  P43

    1.  要点:

        1.  不要为每个类,每个方法建立序列图,这样太浪费时间。

      

        2.  序列图应当用于表现对象间的连接而不是具体的算法细节。

      

        3.  序列图不应有大量的对象和消息返回,而应该抓住本质。

      

        4.  尽量不要用序列图去描述每一个小细节。

      

        5.  代码能足够清晰的说明自己时,图是多余的,浪费的。

      

        6.  应该努力是更多的代码能清楚的描述自己,更少的使用图。(即增强代码的可读性)

      

        7.  小序列图比大序列图容易理解,所以更具有实用价值。

      

        8.  高层图比低层图更有用,因为共性比差异多。

      

        9.  白板上的序列图,用于与同事进行表达、交流。

            文档中的序列图,用于捕获核心的突出的系统协作。

  

    2.  相关术语:

        对象、生命线(life lines)、消息、数据标记(data tokens)、时间(time)、活动(Activation)

      

    3.  生命线

        1.  垂立在对象、类或参与者下面的虚线,与时间同方向。代表对象或参与者的生命周期。

      

        2.  区别对象和类的方法:

            矩形框中对象名下方有横线,类名下方没有横线。

          

        3.  参与协作的对象或类被放置在序列图的顶部横向排开。

      

    4.  人样图

        1.  表示匿名参与者,一般作为消息发起的起点和终点。

      

        2.  并非所有的序列图都有人样图,但大部分都有。

      

    5.  消息

        1.  代表一个对象调用另一个对象(或类)的成员函数。

      

        2.  生命线之间的横向箭头,箭头上方是消息名。

      

        3.  消息的参数使用放在箭头下方的数据标记(data tokens)表示,或者放在消息名后面的括号里。

      

    6.  活动(Activation)

        1.  可选,大多数情况下不使用

      

        2.  沿着生命线的竖向长条形小框

  

    7.  返回值

        表示返回值的横向向左的箭头无须标记名字。

      

    8.  表示创建一个对象的方法:

        一个没有标记名字的消息指向一个被创建的对象上。

      

    9.  表示回收一个对象的方法:

        一个对象的生命线终止在一个“X”上。

      

        消息箭头指向这个“X”,表明一个对象被GC回收。

      

    10. 表示“循环”的方法:

        P49 Figure 4-8

        循环表达式的前缀:

        *[while id:=idList.next()]

  

    11. 表示“分支”的方法:

        P49 Figure 4-8

          

    12. 费时间的消息

        1.  不费时间的消息,完全水平的箭头。

      

        2.  费时间的消息,与水平有个夹角的箭头。

      

    13. 异步消息

        1.  同步消息,使用实心箭头表示。

      

        2.  异步消息,使用空心箭头表示,将消息发送后可立即获回控制权。

      

        3.  序列图可以发现异步系统中的竞争条件(Race condition)。

  

    14. 表示“多线程”的方法:

        P54 Figure 4-12

        消息名称前加上线程标记前缀,来显示几个不同的线程控制。

      

    15. 表示“活动对象(active objects)”的方法:

        活动对象使用粗体框来表示

      

    16. 表示“向接口发送消息”的方法:

        1.  给接口命名对象,然后就像使用一般对象一样来使用。

            这里强调对象符合接口,而不是接口的实例化。

            P55 Figure 4-15

          

        2.  虽然明确知道对象的类类型,但仍要表示消息是被发送到一个接口上。

            P55 Figure 4-16

      

5.  第五章 用例图 (Use Case) 静态图 P57

    1.  概念:

        1.  用例是有关动作性(行为性)需求的文本性描述。

      

        2.  一个用例是有关一个系统的行为的一个描述。

            这个描述是从一个用户的角度编写的。

      

        3.  一个用例捕获一个事件的可视化序列。

            这个事件是一个系统对单个用户的激励(stimulus)的响应过程。

          

        4.  用例不描述系统隐藏着的机制,它只描述那些用户可见的事情。

      

  

    2.  要点:

        1.  诀窍是保持用例的简单。

  

        2.  对于不断发生变化的事情,就不需要过早的去捕获细节。

  

        3.  用例是编写出来的,而不是画出来的。

      

        4.  过早地用用例去记录明天就会发生变化的细节并不值得。

            除非这些用例在近几周内会被实现。

            可以先将这些用例的名称记下来列成表格,维护着。当它们快被实现时,再填充细节。

          

        5.  所有的UML图中,用例图最容易混淆,也是最没用的。但系统边界图除外。

          

    3.  Alistair Cockburn的《有效编写用例》

        书中可了解参与者,次要参与者,前置条件,后置条件等用例的其它要素。

      

    4.  系统边界图

        1.  用途:

            对开发人员提供的信息太少,但可作为向客户讲解的材料。

          

        2.  要素:

            1.  长方形表示系统边界。

          

            2.  长方形里面的任何东西都是需要开发的系统的一部分。

          

            3.  长方形外面是与系统交互的参与者(actors)。

          

            4.  参与者是为系统提供激励的系统外实体。

          

            5.  参与者通常是人类用户,也可以是其它系统,甚至是设备,如实时时钟。

          

            6.  长方形里面的用例(带名称的椭圆形)与刺激它的参与者连接,连线上不带箭头。

          

            7.  尽量忽略用例关系,因为用例关系会引起“扩展”还是“泛化”的争论。

          

6.  第六章 面向对象设计(OOD)原则 P61

    1.  学习下面五个设计原则的目的

        用来评估一组UML图或一批代码是否被适当地设计。

  

    2.  适当设计的系统:

        容易被理解、容易被改变、容易被重用。

        表现为没有特别的开发困难,是简单的、扼要的和经济的。

      

    3.  糟糕设计的臭味的不同成分:

        1.  僵化性(Rigidity)

            难以修改。对一个改动,要修改好几处地方。

          

        2.  脆弱性(Fragility)

            对某个部分的修改,会使不相干的部分出问题。

          

        3.  牢固性(immobility)

            很难拆分成能重用的组件。

      

        4.  粘滞性(Viscosity)

            模块之间结合太紧密,编辑、编译和测试都变得很麻烦。

      

        5.  不必要的复杂性(Needless Complexity)

          

      

        6.  不必要的重复(Needless Repetition)

            存在大量的复制粘贴,代码看起来都很相似。

      

        7.  晦涩性(Opacity)

            代码无法清楚的描述自己。

  

    4.  依存关系混乱的代码就像意大利式细面条般

  

    5.  五种设计原则

        1.  单一职责原则(SRP)

            Single Responsibility Principle

            P62

          

            1.  一个类应当只有一个改变的原因

          

            2.  一个类要处理的事情太多,就会散发出脆弱性的臭味。

          

            3.  书中的例子是一个既要计算薪水,又要读写磁盘,还要打印报表的类Employee。

      

        2.  开放-封闭原则(OCP)

            Open-Close Principle

            P64

          

            1.  应当能够改变一个类的周边环境,而无须改变类本身。

          

            2.  经常违反OCP原则的是GUI

                违反OCP的实现,将所有的行为放入一个使用GUI API的类中。

                遵循OCP的系统,将GUI的操纵与数据的操作分离。

              

            3.  书中的举例是一个数据与操作分离的GUI实现

                P65 Figure 6-6

              

            4.  单元测试的self shunt模式

                http://www.objectmentor.com/resources/articles/SelfShunPtrn.pdf

              

            5.  设计遵循OCP原则,就可以改变dialog和model的周边环境到一个测试环境,而无须对dialog和model作任何修改。

          

            6.  使用抽象(指接口和抽象类)是遵循OCP原则的一个关键。

          

            7.  遵循OCP原则的方法:

                通常是在编写实际代码之前,编写简单的单元测试。这个单元测试使用Test-First(测试优先)方法进行编写。

          

        3.  Liskov替换原则(LSP)

            Liskov Substitution Principle

            P77

      

            1.  避免造成派生类的方法非法或退化,一个基类的使用者应当不需要知道这个派生类。

          

            2.  基类的使用者,为了使用它们的派生类,应当无须做特别的处理。

                这里的特别处理指的是使用instanceof或向下转型(DownCast)操作。

              

            3.  违反LSP原则的两种情况:

                1.  当调用一个派生类的成员函数时发生了非法使用,导致不得不抛出异常。

              

                2.  使用一个退化的派生类的方法,退化是指这个方法什么都不实现。

              

            4.  违反LSP问题的解决方法是:

                为派生类另外寻找一个基类,而不是勉强从现有的基类派生。

              

            5.  书中的举例是把志愿者类作为类Employee的派生类所产生的麻烦。

          

        4.  依存关系倒置原则(DIP)

            Dependency Invertion Principle

            P79

          

            1.  用依赖接口和抽象类来替代依赖容易变化的具体类。

          

            2.  遵循DIP原则可以减少变化对系统的影响,减少系统的敏感度。

          

            3.  从抽象类和接口派生出来的具体类比抽象类和接口的改变频繁得多,

                所以宁可依赖抽象(指接口和抽象类),也不要依赖那些容易变化的具体类。

              

                如果要继承一个类,就从一个抽象类继承。

                如果要持有一个类的引用,就从一个抽象的类引用。

                如果要调用一个函数,就从一个抽象函数调用。

              

            4.  容易变化的具体类是:

                1.  那些正在开发的具体的类。

              

                2.  那些容易变化的捕获商业逻辑的类。

              

                3.  Vector类或String类不算容易变化的具体类。

              

            5.  遵循DIP原则的方法:

                为那些容易变化的具体类创建并依赖于接口。

              

      

        5.  接口隔离原则(ISP)

            Interface Separate Principle

            P79

          

            1.  给一个对象的每一个使用者一个接口,这个接口仅有使用者需要的方法。

          

            2.  肥类(Fat Class)

                一个有着成堆方法的类。

              

            3.  肥类引起的麻烦:

                肥类的使用者不使用类的大部分方法,却会因为这些方法的改变而受影响。

              

            4.  遵循ISP原则的方法:

                为肥类的使用者提供一个只包含它们需要的方法的接口。

              

        6.  设计原则的应用方法:

            1.  试图让系统时时刻刻遵循所有的原则是不明智的。  

      

            2.  应用这些原则的最好方法是反应式(reactively)方法:

                当第一次觉察到代码里有一个结构性的问题存在时,

                或当第一次意识到一个模块的改变被其它模块影响时,

                尝试应用这些原则去解决问题。

7.  第七章 dX实践 P83

    1.  何为dX实践?

        1.  dX实践是一套规则,轻量级的开发过程。

        2.  dX实践其实就是XP(极限编程)实践,XP倒过来就是dX。

        3.  dX实践是短周期迭代式处理所有事情。

            所有事情包括需求分析、设计实现、测试和文档。

            短周期(即迭代周期)就是两个星期。

    2.  初始探索

        1.  第一次迭代探索的是需求,一般不需要花费两周的时间。

        2.  客户是负责需求和负责决策的人。

        3.  与客户讨论的内容:

            1.  系统怎样运作,一些必须的功能。

                不用作详细记录,目标是搞清楚系统的整体状况。

            2.  识别出用例(Use Case)

                把用例名记录在索引卡片上,卡片就是User Story。

                卡片上还可记些其它重要信息。

    3.  功能特征评估:

        1.  对User Story评估,计算系数。

        2.  评估方法:

            1.  以一个已知Story的评估结果作为基础,根据新的User Story的难易程度进行评估。

            2.  用“完美编程”的天数作为标准。

                “完美编程”就是不受任何干扰,在极其理想的环境下编程。

        3.  评估之后要对User Story进行合并和拆分。

            一个User Story的天数应控制在1天到4天之间。

            避免高估自己实力,或评估太保守。

        4.  花两到三天的时间,很快地粗糙地实现两、三个比较有趣的User Story。

            目的是验证评估,获得点数和人天的对应关系。

            这里的人天是粗糙实现得到的。保质保量的实现,一般是粗糙实现的3倍。

    4.  探索

        1.  计算初始速度

            初始速度 = (3 乘以 粗糙实现的人天)除以 被粗糙实现的Use Story的总点数。

    5.  计划

        以计算得到的速度作为标准,计算每次迭代周期中需完成的Story。

    6.  发布计划

        1.  典型的一次发布周期,包括六次迭代周期即三个月

            如果团队有五人,一次迭代周期是两周(十个工作日),

            那么一次迭代周期为50人天,一次发布周期为300人天。

        2.  一次发布周期可完成的点数=300人天 × 速度。

        3.  客户挑出点数总数为(300人天×速度)的最重要、最有效的User Story,作为发布计划。

    7.  迭代计划

        1.  一次迭代周期为50人天。

        2.  一次迭代周期可完成的点数=50人天×速度。

        3.  把User Story再细分成任务。

            这里的任务是单个开发人员能够负责的简单任务,以4到10人小时为单位。

            这个细分过程需要客户协助识别重要和次要的用户接口。

        4.  细分结束,开发人员挑选符合自己预算的任务。

            对于剩余任务要进行分摊。

            最后的未决任务要和客户商量是否挪到下一个迭代周期。

            直至所有的任务都分配出去。

    8.  中点

        根据前半段迭代周期中完成任务的点数,对后半段剩下的任务进行调整,取消或增加任务。

    9.  速度反馈

        1.  迭代周期结束的时间不能变更。

        2.  根据实际完成的点数重新计算速度,作为下个迭代周期的依据。

        3.  新速度是上一个迭代周期完成的实际点数。

    10. 将迭代与管理阶段联系起来

        1.  “统一过程”项目的四个管理阶段:

            1.  初始阶段

                确定系统的可行性和商业案例。

            2.  细化阶段

                确定系统架构并创建一个比较可靠的实现计划。

            3.  构造阶段

                开始进行系统实现。

            4.  移交阶段

                安装系统,和用户一起测试(UAT测试)。

    11. 一个迭代周期中包括了:

        1.  分析需求

        2.  设计解决方案

        3.  实现解决方案

            只考虑当前迭代期间需要处理的User Story。

    12. 结对开发

        两个开发人员用同一台机器工作,一起处理他们负责的任务。

    13. 可验收测试

        1.  每个迭代周期开始时,客户和QA一起把User Story充实到Use Case,并为之编写可执行的验收测试案例。

        2.  对于程序员验收测试案例就是需求文档。

        3.  整个迭代周期中,程序员持续的运行测试案例,以保证能正确的通过验收测试。

    14. 单元测试

        1.  代码未动,测试先行。

        2.  如果有任何一个单元测试没有通过,就不能编写新的产品代码。

        3.  极限迭代的过程:

            1.  先写一段5到10行的单元测试代码。

            2.  然后为了使这段单元测试代码能够编译通过,开始编写并不断充实产品代码。

            3.  一旦单元测试通过之后,就可以添加新的代码,开始新的迭代。

            4.  一个测试周期通常是1到10分钟。

        4.  极限迭代的目的:

            无论现在进展到什么程度,几分钟前的产品代码总是可以运行的。

        5.  单元测试也是文档的一种形式。

        6.  单元测试代码提供的信息有:

            1.  如何去调用一个特定的API。

            2.  如何创建一个特定的对象。

        7.  这种形式的文档是明确的,准确的,可编译的和可执行的。

    15. 重构:

        1.  只要用大量的单元测试和验收测试作靠山,就可以放心大胆的去修改那些需要修改的任何部分。

        2.  在不改变程序的行为的前提下,改进程序的内部结构就是重构。

        3.  每小时左右的编程结束后,就是几分钟小碎步式的重构,然后测试。

        4.  绝不能把烂代码留到第二天。

    16. 开放式办公环境:

        1.  成员之间有着非常频繁的交流和沟通,可以快速的互相提问,得到最快的响应和建议。

            做到互相依靠,互看代码。

            方便结对编程。

    17. 持续集成:

        1.  check in的规则:

            只有通过单元测试和验收测试的代码才能check in。

        2.  持续性的集成可以避免项目进度到了尾声才来一个非常庞大的终极集成。

    18. 文档:

        1.  Martin文档第一要律:

            只编写那些真正需要的有意义的文档。

        2.  不需要专门用类图来捕获所有的需求。

        3.  不需要在序列图里捕获所有的Use Case。

        4.  只有真正需要使用这些工具的时候才使用,否则就让它们一边歇着去。

8. 第八章 包(Packages)P92

    1.  Java的两类重要的包:

        1.  源代码包。package

        2.  二进制组件。.jar

    2.  Java Packages

        1.  Java Packages是名称空间(Name Spaces)

            它们允许程序员创建小的私有空间,以便在其中声明类。

            这些类的名字不会与其它包中同名的类发生冲突。

        2.  UML中表示一个包的几种方式:

            1.  包的图标是一个矩形框,在其顶部有一个标签,像一个文件夹。

                完整的包名显示在矩形框中间。

                P92 Figure 8-1

            2.  也可以将完整的包名写在矩形框上的标签中。

                剩下大的矩形框中列出包中定义的所有类。

                P92 Figure 8-2

            3.  可以使用包含关系(contains)显示包的嵌套结构。

                P93 Figure 8-3

        3.  依赖(Dependencies)

            在同一个包中的代码常常依赖另一个包中的代码。

            在UML中用依赖关系(dependency)表示这种依赖性。

            P93 Figure 8-4

            import不会创建真正的依赖关系,只有调用函数才会创建依赖关系。

    3.  二进制组件.jar文件(Binary Components)

        1.  UML中表示一个.jar组件的方式

            P94 Figure 8-5

        2.  一个组件常常包含一个或多个包,所以组件之间的依赖关系通常是包之间依赖关系的子集。

    4.  包设计的原则(Principles of Package Design)

        1.  遵循原则的作用:

            1.  易变的类放在一起。

            2.  将因为各种原因需要被改变的类分离开。

            3.  将经常改变的类和不常变化的类独立开。

            4.  分离系统的高层结构和底层实现细节。

        2.  发布/重用等价原则(The Release/Reuse Equivalency Principle)(REP)

            1.  被重用的一组类应该放到一个包中。然后这个包被那些重用它们的开发人员发布和跟踪。

            2.  创建一个包是为了方便别人重用。

            3.  重用的粒度就是发布的粒度。

                重用的最小的东西,是值得别人去发布和跟踪的。

        3.  公共闭合原则(The Common Closure Principle)(CCP)

            1.  CCP相当于OOD的单一责任原则(SRP)

            2.  由于相同原因要被修改的类放在一个包中。

        4.  公共重用原则(The Common Reuse Principle)(CRP)

            1.  CRP相当于OOD的接口隔离原则(ISP)

            2.  应该尽可能地将只被一个客户使用的包与被多个不同客户使用的包分开。

            3.  避免对包中某个类的修改会影响到其它没有使用该类的客户。

        5.  非循环依赖原则(The Acyclic Dependencies Principle)(ADP)

            1.  包的循环依赖将导致编译和开发方面的问题。

            2.  应避免在依赖图中出现循环依赖。

            3.  可以使用JDepend等工具,来检查是否存在循环依赖。

        6.  稳定依赖原则(The Stable Dependencies Principle)(SDP)

            1.  包不应该依赖那些比它们自己更不稳定(更易改变)的包。

            2.  每个包所依赖的包应当比依赖它们的包更稳定。

            3.  如果一个包有多个指向它的依赖,而它自己又依赖一个易发生改变的包,其结果就导致这个包很难改变。

        7.  稳定抽象原则(The Stable Abstractions Principle)(SAP)

            1.  SAP相当于OOD的开放-封闭原则(OCP)

            2.  为了保证稳定的包易被控制,稳定的包应该是抽象的。

                越稳定的包应该越抽象。

                抽象类和接口的比例越大的包就越抽象。

            3.  SDP原则和SAP原则相结合就成了包版本的依存关系倒置(DIP)原则。

            4.  结合SDP原则和SAP原则可得出:

                1.  稳定性随指向它的依赖的增多而增加。

                2.  抽象性应该随稳定性的增加而增加。

                3.  所以,抽象性应该随指向它们的依赖的增多而增加。

            5.  包依赖图对于解决依赖循环问题和判断编译顺序都很有帮助。

9. 第九章  对象图(Object Diagrams) P98

    1.  UML对象图就像系统运行时的一个快照。

    2.  对象图包含的信息有:

        1.  系统在某个特定时刻,或者系统处于某个特定状态时的内部结构。

        2.  对象和关系被实际使用的方式。

        3.  系统根据不同输入的变化情况。

    3.  对象图被使用的情况很少。

    4.  对象图所用的标记与类图相同。

    5.  对象图的另一个有用之处是在多线程系统中。

        1.  主动对象(Active Object)

            用粗线条框表示。

        2.  主动对象就像是线程的控制者。

            它们包含有控制线程的方法,如:Start、Stop、SetPrioring等。

            P102 Figure 9-4

    6.  在多线程系统中,对象图比类图更具有表达力的原因:

        这段程序结构是在运行时建立的,这是一种关于对象的结构而不是关于类的结构。

    7.  很多对象图能从类图直接推断出来,所以对象图应用的比较少。

10. 第十章  状态图(Stat Diagrams)P103

    1.  状态转换图(State Transition Diagrams)(STD)

        P103 Figure 10-1

        1.  状态

            使用圆形拐角矩形表示。

        2.  状态的名字

            放在圆形拐角矩形上面的框格中。

        3.  进入或退出状态时触发的动作。

            放在圆形拐角矩形下面的框格中。

        4.  状态之间的转换

            使用箭头表示,箭头指向表示从原状态到目标状态。

        5.  状态转换箭头上标记:

            1.  触发转换的每一个事件的名称。

            2.  当转换被触发时执行的动作。

        6.  初始伪状态(Initial Pseudo State)

            使用实心的黑色圆圈表示。

            标明了有限状态机生命周期的起始状态。

        7.  超状态(Super State)

            超状态适用于有多个状态要用相同的方式响应某些相同事件的情况。

            画一个超状态把那些类似的状态括起来,然后只需从超状态画一个状态转换箭头,

            来代替从每一个状态画转换箭头。

            超状态的转换可以被子状态的转换重载。

            P106 Figure 10-5

            超状态和一般的状态一样有entry、exit和专用事件。

            注意:超状态和其子状态的事件调用顺序。

            P106 Figure 10-6

        8.  专用事件

            表示状态的圆形拐角矩形的下面框格中包含了多对事件和动作。

            事件和动作的书写形式:event/action

            两个标准的事件是entry和exit。

            可以自定义事件。

        9.  初始伪状态和结束伪状态。

            初始伪状态不需要有事件,但可以有一个动作。

            这个动作是在有限状态机被创建以后,第一个被调用的动作。

            转换到结束伪状态时的动作是有限状态机最后执行的一个动作。

        10. 有限状态机图的使用:

            对于日趋完善中(即频繁变更中)的系统,

            在文档中创建STTS(State Transition Tables)要好于使用STDS(State Transition Diagrams)。

            在开发和维护有限状态机方面,使用文本语言比图形更加简单。

 

 

--------------------------------------------------------------------------------

版权所有:UML软件工程组织