Together ControlCenter 入门实践教程


Together ControlCenter 6.0 入门实践教程 翻译:李颖(ew@263.net) PDF制作:禹国旭 (spymaster@163.com) 以下页面为 Together 新手提供了向导和教程 . 完成本教程后, 你应该对 Together 足够熟悉, 可以从头开始创建一个应用了. 请准备 好几个小时来阅读这些简单的介绍, 对于更深入的讲解需要花更长的时间. 目录: ƒ 如何使用本实践教程 ƒ 简介: 如何操纵 Together ƒ 教程: 从头创建一个 Together 工程 ƒ 软件需求环境及附加资源 如何使用本实践教程 可以用很多方式来描述 Together. 它是一种类建模工具, 时刻保证代码与模型图同步. 它是一种架构设计向导, 用来设计工程的物理和 逻辑结构. 它是分析者, 设计者, 开发者以及程序员之间的主要沟通渠道. 它是一种可定制的 Java?, C++, Visual Basic? 以及 C# 编程 环境, 并能在软件开发过程中促使你遵循良好的软件工程规范. 它是一种企业级开发支持环境... 等等等等. Together 是易于使用的, 而且包含丰富的特性. 本实践教程包含一系列课程, 将快速地教给你一些 Together 工作知识. 教程主要由 两部分组成: 1. 简介 -- 演示如何操纵 Together. 2. 教程 -- 演示如何从头创建一个工程. 整个教程由许多实际操作步骤组成. 操作步骤用以下方式表示. 操作步骤 : 你需要完成某任务. 每个操作步骤后跟随着详细的解释, 包括告诉你如何完成任务的屏幕截图以及相关信息. 你应该先阅读简介. 我们强烈建议你完成 简介中的每一个操作步骤 , 或者至少进行一些有意义的探索. 当你学会如何操纵 Together 后, 你就可以学习教程了. 我们当然不可能告诉你关于 Together 的所有信息, 但本教程可以引导你入门. 当你使用 Together 进行工作的时候, 将会发现很多本 教程没有涉及的特性. 玩得开心! 简介: 如何操纵 Together 简介将介绍 Together 用户界面的结构和功能 . 它还将告诉你如何定制 Together 以适应你的工作需求. 1. 主窗口(Main Window) 2. Explorer 面板 3. 在 Together 中浏览 4. 通过 Options 和 Inspectors 进行定制 教程: 从头创建一个 Together 工程 教程将引导你通过多个操作步骤创建一个 Java 应用, 它覆盖了 Together 的基本特性. Together 教程是基于 Java 的, 但程序员还 是可以在其他语言下很容易地模仿这些操作步骤. (教程只需要很少的 Java 知识.) 1. 工程和包 2. 需求与用例图(Use Case Diagrams) 3. 业务规则与活动图(Activity Diagrams) 4. 图(Diagrams)与类(Classes) 5. 类(Classes)与关联(Associations) 6. 模板模式(Template Patterns) 7. 使用类模式(Class Patterns)进行代码重构(Refactoring) 8. 时序图(Sequence Diagrams) 9. 文档生成 10. 审查(Audits)与统计(Metrics) (需要 Together ControlCenter) 11. 运行和调试 Java 工程 软件环境需求及附加资源 本实践教程不需要特定的软件支持. Together Solo 对于大多数工作已经足够了 , 但你仍然需要 Together ControlCenter 支持某些高 级特性. Together 产品系列, 包括 Together ControlCenter 和 Together Solo, 可在 www.togethersoft.com 下载. Together ControlCenter 中包含了更多的特性, 并可免费试用 15 天. Together Solo 是比较小型的版本 , 可免费从 www.togethercommunity.com 获得. Together 软件包含了完成的文档集. Together 用户可以通过设在 Together Community 站点, www.togethercommunity.com 上的论坛来进行讨论. 一: 工程和包 Together 教程的范围包括 Together 中大部分常用的特性. 我们将向你演示如何创建自己的工程; 后面的课程将引导你进行设计和实 现. 这一课将介绍一些基本知识. 如果你是 Together 新手, 并且感觉使用 Together 还存在困难, 那么请在开始本课程前先学习 Together 简介. Together 最早并延续至今的特性之一就是保持类模型与代码的同步 -- 任何时刻都是如此. 这就是 Together 所谓的 LiveSourceTM 技术. 下面你将看到这一特性. 内容 ƒ 创建新工程 ƒ 修改工程设置 ƒ 在 模型图和主根目录下工作 ƒ 创建新包 ƒ 显示包依赖关系 ƒ 技巧 创建新工程 Together 教程的大多数内容都围绕这个示例问题: "一个小型地区航空公司需要一个应用程序, 用于统计航班预定和机票收入情况." 解决这个问题的第一步是创建一个 Together 工程, 以便开发一个完整的解决方案. 操作步骤 : 创建一个新的工程, 命名为 airline. 打开 Together 并在主菜单中选择 File | New . 在 Object Gallery 对话框中: 1. 在左侧的 Categories 面板中选择 General . (General 是缺省选项.) 2. 在右侧的 Template 面板中选择 New Project. Together 将显示 New Project 对话框, 在对话框中你可以输入工程名(airline)和目标语言(Java). 然后点击 Finish 完成整个过 程. 下图显示了 Object Gallery 对话框和 New Project 对话框. 除非你指定, 否则 Together 将在 $TOGETHER_HOME$/myprojects 内为新工程创建新目录 . 目录名与工程名一致. Together 允许选择五种语言: Java, VisualBasic, VisualBasic.Net, CORBA IDL, C#, 和 CORBA IDL. 如果你只打算设计 , 你可以创建一个与 语言无关的工程(将 default language 设置为 Design). 一个工程最少包括: ƒ 一个工程文件(.tpr 扩展名和 图标) ƒ 缺省包模型图(default.dfPackage) ƒ 主根目录 我们创建 airline 工程时, Together 将在主根目录 airline 下创建三个文件. ƒ default.dfPackage ƒ airline.tpr ƒ airline.tws (工作台设置) 如果你在 Windows 平台下工作, 你可能还会看到 Windows 元文件. (你可以在工程设置或缺省设置中关闭产生元文件的选项.) ƒ default.dfPackage.wmf (Windows 元文件) Explorer 面板 Directory 页中的 User Projects 文件夹对应于物理目录 $TOGETHER_HOME$/myprojects. airline 的主 根目录在 User Projects 下. 当 airline 打开后, 它的主根目录将出现在 Current Project 下. 修改工程设置 Together 允许用户在缺省, 工程, 和模型图三个级别中修改工作环境. 编辑器也右独立的设置. 工程打开后, 你可以在任何时刻修改工 程设置. 操作步骤 : 修改 airline 工程设置使得工程中的模型图不显示点状的网格. 要修改工程设置, 在主工具条中选择 Tools | Options | Project Level . Together 显示类似下图的对话框. 展开 Diagram 以便设置 Grid 选项. 取消 Show Grid 项将隐藏工程内所有模型图中的背景网格. 我们将在以后的所有的例图中关闭网格线. 你可以点击 Ok 或 Cancel 关闭对话框. 在 模型图和主根目录下工作 Together 为每个新工程生成一个 模型图. 模型图显示主根目录下的包, 也显示源代码文件在主根目录下的类. (Default 模型图以及工程中包的模型图都使用 图标. 它们是物理类的模型图.) 当工程初次创建时, 模型图只是一片简单的空白. 下面是新创建的工程在 Explorer 面板中的显示. Directory 页. 工程初次创建时主根目录(airline) 不包含其他目录 后缀 .tpr 表示 Together 工程文件. 后缀 .tws 表示 Together 工作台设置文件. 这三个文件都时 ASCII 文件. Model 页. 这里只有模型的一部分. 开始的时候其中没有任何元素. 创建新包 模型图是将一个工程组织为包的起始位置. airline 工程最终包含三个包. 操作步骤 : 在 模型图中创建一个新包, 命名为 ProblemDomain. 要创建一个新包, 请在 Designer 面板的垂直工具条上点击包按钮 ( ). 然后点击模型图的背景. 模型图将生成 一个新节点. 此时, 你可以直接在节点的内嵌编辑器中直接输入包的名字. 按 Enter 确认. 由于你创建了一个包, 你现在可以看看 Together 的 LiveSource 技术已经生效了 -- Together 为这个包自动创建了一个物理目录并 在目录下生成了一个缺省的模型图. 新的模型图将显示 Together 当前或以后发现的任何物理工程内容. 在 Designer 面板中, 模型图现在包含一个单独的节点 , 它是一个包. Explorer 面板的 Model 页显示新的包节点. 新包中包括一个新的模型图节点, 它 们的名称与包相同. 新包和新模型图现在都是空的. Explorer 面板的 Directory 页显示工程新的文件结构. 主根目录下出现了新的子目录, 名为 ProblemDomain. 这个目录包含 ProblemDomain.dfPackage 文件, 它是新包缺省的模型图文件. 要察看新的 ProblemDomain 模型图的内容, 请在 Explorer 面板的 Model 页双击模型图. 或者使用模型图的右键菜单将它在新的 页中打开. 操作步骤 : 在 模型图中再创建两个包: UserInterface 和 DataManagement. 下面是创建多个包的示例图. 按 并在工具条中点击包按钮将使得按钮被按下. 按钮被按下后就可以在 Designer 面板中多次创 建包并修改名称, 而不需要再回到工具条点击按钮. 要释放按钮, 只需要再次点击它即可. (如果你不慎再模型图中创建了太多的包, 主工具条中的撤消按钮可以删除它.) 显示包依赖关系 Designer 面板包含一个垂直工具条, 提供了创建 UML 模型元素的整套工具. 操作步骤 : 创建从 UserInterface 到 ProblemDomain 的依赖关系. 要创建包依赖关系, 点击依赖按钮(图标是虚线箭头 ). 然后在模型图中点击依赖包("client" ) 并将箭头的末尾 拖动到被依赖的包("supplier"). 你的依赖关系将类似例图的样子. 如果工具条太短, 点击底部的 More 按钮( ). Together 将可用的按钮显 示在小条中. 你可以使用依赖关系的察看器修改其属性, 包括修改它的标签, 选择策略, 以及设置 supplier 和 client 的角色. 要访问属性察看器, 在依赖关系上点击鼠标右键并在右键菜单中选择 Properties. 技巧 ƒ 最好以你的操作系统中合法的文件名做为包的名称. 不要在包名称中插入空格, 标点符号或其他特殊字符. ƒ 后缀 .tpr 表示 Together 工程文件. Together 将它的所有文件以简单 ASCII 文本的形式保存 -- 你可以使用普通的编辑 器察看它们. ƒ 永远将你的工程组织为包的形式. ƒ 要创建多个同类型的节点, 按 并在垂直工具条中点击按钮, 使得它被按下. 此时你还是可以使用内嵌编辑器. 再次点 击按钮将释放它. 二: 需求与用例图 任何一个软件项目都必须首先确定它的特性. 航空公司的项目可能是一个非常大的问题, 但你可以只集中精力实现少量的需求. ƒ 预定航班. ƒ 购买机票. ƒ 确定航班上是否还有足够的座位可以预定. ƒ 计算航班的机票收入总数. 在这一课中, 你将创建一个用例图来捕捉这些需求. 目录: ƒ 创建新的模型图 ƒ 创建角色, 用例和系统边界 ƒ 连接模型元素 ƒ 删除模型元素 ƒ 技巧 创建新的模型图 打开你在前面部分中创建的 airline 工程. 将焦点切换到 模型图中(将它在 Designer 面板中切换到最前). 操作步骤 : 创建一个新的用例图, 命名为 MakeReservation. 创建完成后, 在当前模型图中放一个 MakeReservation 的快捷连 接. 有几种不同的方法创建新的模型图. ƒ 按以下步骤执行: 1. 在主菜单中选择 File | New 或者 在主工具条中按 New 按纽( ). 2. 在对话框中, 在范围中选择 General 并在模板中选择 New Diagram . ƒ 或者 在 Designer 面板的菜单工具条上点击 New diagram 按纽( ). Together 显示一个新建模 型图的对话框, 如右图所 示. 点击 Use Case 的图 标选中它. 模型图名称在第一个文本框 内输入. (如果你不是在 模型图中开始 上述操作的, 请从包名称列 表中选中 模 型图.) 你在底部文本框中输入的描 述信息将供 Together 生 成文档时使用. 描述信息上放的选择框表示 是否为新建的模型图建立快 捷连接. 快捷连接在当前模型图 ( Designer 面板中获得焦 点的模型图)中表现为一个 节点. 点击快捷连接将聚焦 到对应的模型图. 点击 Ok, 新建的模型图将出现在 Explorer 面板的 Model 页, Directory 页, 和 Diagram 页中. 它将成为 Designer 面板中的当 前模型图. 创建角色, 用例和系统边界 新建的用例图 MakeReservation 现在将在 Designer 面板中获得焦点. 操作步骤 : 在模型图中放置一个系统边界, 并将其命名为 Airline Reservation System. Designer 面板的垂直工具条中的按纽将根据模型图类型的不同而不同. 用例图中的工具条按纽包括 角色, 用例, 系统边界, 和连接它 们的关系. 点击系统边界按纽( ) 然后点击模型图, 这样将创建系统边界. 在 内嵌编辑器中输入系统边界的名称. 完成这一步后, 你可以移动系统边界并修改其大小. 右图演示了拖 动它的一个角来修改其大小. 操作步骤 : 创建三个角色: Passenger, Finance Officer, 和 Agent. 点击角色按纽( ) 然后点击模型图, 这样将创建角色. 你必须点击系统边界之外, 以便将角色放置在模型图中. 在内嵌编辑器中输入角色名称. 如果你按 并点击角色按纽 , 那么你可以一次创建多个角色而不必回到 Designer 工具条中再次点击按纽 . 在这个过程中你仍然 可以输入角色名称. 这是工具条中大多数元素按纽的工作方式, 按 并点击按纽 , 将使得它"粘住". 要释放按纽 , 只需要再次点击 它. 操作步骤 : 创建四个新的用例: 1. Make a Reservation 2. Check Availability 3. Buy a Ticket 4. Find Ticket Revenue 点击用例按纽( ) 然后点击模型图, 这样将创建新的用例. 使用内嵌编辑器输入描述文本. 你可以创建一个用例, 然后将它拖动到系统边界内. 或者你可以直接再系统边界内创建用例. 你随时可以用鼠标拖动一个模型元素来改变 它的位置. 移动系统边界时其中的用例也会随之移动. 连接模型元素 通信(communication)表示角色与用例的连接 . 它表示角色参与了用例的活动. 我们的模型图中 Agent 将参与三个用例. Passenger 将参与两个用例, Finance Officer 只参与一个用例. 操作步骤 : 创建通信连接: 1. 从 Passenger 到 Make a Reservation 2. 从 Passenger 到 Buy a Ticket 3. 从 Agent 到 Make a Reservation 4. 从 Agent 到 Buy a Ticket 5. 从 Agent 到 Check Availability 6. 从 FinanceOfficer 到 Find Ticket Revenue 你可以用同样的方法创建任何连接元素(通信(communication), 依赖(dependency), 关联(association), 等等). 首先在 Designer 工具条中点击通信按纽( ). 当你将光标移动到正确的源元素上, 它的周围将显示一个光环. 点击源元素选中它, 然后拖动到目标元素. 当鼠标移动到正确的目标元素上, 它的周围也会显示光环. 释放鼠标按纽, 这样将选择目标元素并创建一个连接. 角色可以是通信连接的源或者目标(但不能同时是源和目标!). 你可以从用例连接到角色, 或者相反. 连接的开始处称为 "client." 结束 处称为 "supplier." 操作步骤 : 连接用例: 1. Buy a Ticket 扩展 Make a Reservation. 2. Make a Reservation 包含 Check Availability Designer 面板工具条包括扩展按纽( ) 和包含按纽( ). 这两种连接的源元素和目标元素的选择是非常重要的. 例如, 当你使用扩展 连接时, 请确定 Buy a Ticket 是源元素, Make a Reservation 是目标元素. 操作步骤 : 确定所有的用例都在系统边界内. 如果需要的话, 拖动用例并调整系统边界的大小. 右图是我们的模型图. 你可能需 要将你的模型元素重新排列一下 以便与我们的图看起来一样. 你 可以单独的拖动每个元素, 或者 你也可以套住多个元素同时拖动 它们. 用例图在 模型图中 的快捷方式类似下图所示. (双击 快捷方式将焦点到对应的模型 图.) 删除模型元素 操作步骤 : 按照以下步骤弄乱你的用例图: 1. 创建一个新的用例(名称任意). 2. 在新建用例和 Agent 之间创建通信连接. 3. 创建从 Check Availability 到新建用例的扩展连接. 然后删除新建用例, 观察 Together 如何重新排列模型元素 . 你的模型图可能有些混乱了, 你需要将它恢复到原先的状态. Together 主工具条上的撤消按纽( )可用来防止误操作. 但是如果需要撤消的步骤太多, 撤消按纽可能不是最佳选择. 操作: 删除新建用例 . 在模型图中选中新建用例并按 键将删除它. (或者从元素的右键菜单选择 Delete.) 你这样做之后, 这个坏的用例将连同它的 所有连接一起消失. 你不需要逐个地删除它的连接. 技巧 ƒ 有三种简单的方法来重命名角色, 用例, 或系统边界. ƒ 双击模型元素显示它的内嵌编辑器. ƒ 使用元素右键菜单中的 Rename 项. ƒ 在元素属性编辑器的 Properties 页中修改名称. ƒ 要在模型图中修改用例, 角色, 或系统边界的大小, 可以选中它, 然后拖动它的一个角即可. 要改变其形状, 拖动它的上下边或 侧边即可. ƒ 如果你执行了误操作, 可以使用撤消按纽. Ctrl+Z 是撤消的快捷键. Ctrl+Y 是重做的快捷键. (misc.config 文件将缺省的撤 消操作缓冲区大小设置为 4096 KB. 你可以编辑这个文件来修改该设置.) 三: 业务规则与活动图 业务规则中包含了问题的部分需求. 在前面用例图的讨论中我们将航空公司的需求限制为以下四点: ƒ 预定航班. ƒ 购买机票. ƒ 确定航班上是否还有足够的座位可以预定. ƒ 计算航班的机票收入总数. 在这一课中, 我们将通过活动图来确定 "预定航班" 的具体含义. 目录: ƒ 基于业务规则创建活动图 ƒ 使用泳道来组织活动, 开始状态和结束状态 ƒ 创建活动和转换 ƒ 使用分支, 合并和决策改变控制流 ƒ 技巧 基于业务规则创建活动图 你怎样才能 "预定航班" 呢? 我们的航空公司使用以下业务规则 (不可否认非常幼稚): 如果售出的机票数不超过该航班容量 , 那么你可以预定航班 . 现在我们来关心一下当用户请求预定航班时到底发生了哪些事情. 操作步骤 : 在 模型图中新建一个活动图, 命名为 Request Reservation. 点击 Designer 面板水平 工具条中的"New Diagram"按纽( ). 模型图名称在 "New Diagram" 对话框最上方的 文本框中. 我们再次看道, 描述信息对 文档时很重要的, Together 可以用描述信息来生成工程 文档. 如果你选择了 "include in current diagram," 模型图中将显示活动图的一 个快捷方式. 在这一课中, 垂直工具条中的下列八个活动图按纽是非常有用的. 泳道 转换 开始状态 水平分支 结束状态 垂直分支 活动 决策 使用泳道来组织活动, 开始状态和结束状态 我们把 "预定航班" 的请求分为三个部分. ƒ Airplane/Flight Description 用于航班容量 ƒ Flight Reservations 用于已预定信息的列表 ƒ Reservation/Ticket Services 用于创建预定信息并发出机票 现在确定泳道与实际对象的对应关系还太早. 我们可以等到设计类图时再做决定! 操作步骤 : 在模型图中建立三个泳道. 1. Airplane/Flight Description 在左侧 2. Flight Reservations 在中间 3. Reservation/Ticket Services 在右侧 要创建泳道, 点击 Diagram 面板垂直工具条中的 "swimlane" 按 纽( )即可. 你可以点击泳道名称, 并在内嵌编辑器中修改其名称. 你也可以拖动 它的一个角来修改其大小. 此时模型图类似下图. 操作步骤 : 在模型图顶部(泳道上方)放置一个开始状态, 在泳道下方放置一个结束状态. 这一步很简单: 点击 "start" 按纽, 然后点击模型图; 点击 "stop" 按纽, 然后点击模型图. 创建活动和转换 活动图的初始活动将接受一个 "预定航班" 的请求. 操作步骤 : 创建一个活动, 命名为 Receive request, 并将它放置在 Flight Reservations 泳道内 . 将一个转换从开始状态连接 到这个活动. 在活动图中创建活动与在用例图中创建用例类似. 点击工具条中的 "activity" 按纽( )即可. 你 可以四处移动一个活动, 你可以使用内嵌编辑器修改活动名称. 活动图中的转换与用例图中的通信类似. 点击工具条 "transition" 按纽( ), 当你将光标移动到 合法的转换源或目标元素时, Together 将在其周围显示光圈. 右图时创建一个从开始状态到活动的转换的示例图. 操作步骤 : 再创建五个活动" 1. Get capacity (cap) -- 在 Airplane/Flight Description 涌道中 2. Get #tickets -- 在 Flight Reservations 涌道中 3. Create reservation-- 在 Flight Reservations 涌道中 4. Refuse request -- 在 Flight Reservations 涌道中 5. Issue ticket -- 在 Reservation/Ticket Services 涌道中 与创建多个用例一样, 这里也可以使用按 然后点击按纽的方式创建多个活动 . 当你用这种方法在模型图中创建活动时, 你可以 在内嵌编辑器中输入活动名称, 然后在模型图中再次点击以继续创建活动. 创建活动后, 可以将它拖动到任何一个涌道中(或者完全在涌道之外). 使用分支, 合并和决策改变控制流 在我们的航空公司可以预定航班之前, 它必须先检查飞机上是否还有空间. 这就是业务规则出现的地方. Get capacity 和 Get #tickets 可以按任意的顺序执行. 但预定航班的活动开始前, 它们都必须已经完成. 操作步骤 : 创建一个分支. 创建一个从 Receive request 到分支的转换. 然后创建从分支到 Get capacity 和到 Get #tickets 的转换. 模型图工具条按纽中可以选择两种分支按纽: 水平分支( ) 或垂直分支( ). 选择哪种分支只取决于你希望模型图的外 观是什么样子. 分支可以是转换( )的源或目标. 当创建一个到分支的转换时 , 注意看清楚光圈的位置 . 分支比较细, 因此很容易误操作, 将转换目标设置到涌道上. 如果你试图将转换目 标设置到一个不合法的目标元素, Together 将在 Message 面板输出一个红色的错误信息 , 并显示一个错误框, 类似下图所示. 操作步骤 : 创建一个合并. 然后创建从 Get capacity 和 Get #tickets 到合并的转换. 合并按纽于分支按纽一样. 你可以选择水平合并按纽或垂直合并按纽, 你选择哪个按纽只取决于你希望模型图的外观是什么样子 操作步骤 : 创建一个决策节点, 用于比较航班售出的机票数和它的容量. 创建从合并到决策的转换. 然后创建从决策到 Create reservation 和到 Refuse request 的转换. 决策按纽是模型图工具条中的菱形按纽( ). 为了使模型图显示为右图中的样子, 我们将模型图设置为显示矩形连线. 可 以通过主菜单中的 Tools | Options | Diagram Level 来进行设置. (Together 简介的 定制课程中包含了更详细的信息) 从决策种流出转换都需要标记边界条件, 这些边界条件将决定到底执行哪一个转换. 操作步骤 : 为决策种流出的转换设置如下边界条件: ƒ 流向 Create reservation 的转换, 将边界条件设置为 #tkt < c ƒ 流向 Refuse request 的转换, 将边界条件设置为 #tkt >= c 将 "requirement type"属性设置为 "business rule". 输入注释信息, 供以后生成工程文档时使用. 转换也有属性查看器, 你可以通过其右键菜单访问. 在转换线上点击鼠标右键, 以便 访问属性查看器, 如右图所示. 连接的属性查看器中包含 "Link" 页, 其中包含一个文本框 , 可输入边界条件. "Requirements" 页中包含一个文本框可选择多种 "business rule". "Description" 页包含一个文本框可输入注释信息. 操作步骤 : 创建第二个决策. 创建四个转换: 1. 从 Create reservation 到新建决策 2. 从新建决策到 Issue ticket. 边界条件设置为: ticket now 3. 从新建决策到 stop. 边界条件设置为: ticket later 4. 从 Refuse request 到 stop. 5. 从 Issue ticket 到 stop. 边界条件在模型图中显示在一对方括号中. 你可以拖动边界条件或活动来改变模型图. 下图是我们已完成的活动图. 技巧 ƒ 活动图类似流程图. 我们使用它们来描述复杂的业务规则. ƒ Together 不在代码和活动图之间建立直接的关联. 活动图对于草拟活动的流程是很有效的. 但活动图不需要描述具体的消息, 消息顺序, 和控制结构. ƒ 如果 Together 不知道你想将一个转换的结束点放置在哪里时, 它将显示一个 "Choose Destination" 对话框, 使得你可以选 择可用的结束点. ƒ 可以使用主菜单中的 Tools | Options | Diagram Options 命令将连线的显示方式从矩形修改为直线. ƒ 绝大多数模型元素都有右键菜单, 可供你访问或修改元素属性. ƒ 你可以通过转换本身来访问它的右键菜单, 也可以通过任何一个附属于转换的元素(比如一个边界条件)来访问转换的右键菜单. 四: 模型图与类 你现在已经创建了一个新的工程, 并将你的工作组织成了包的形式. 而且你通过用例图大致描述了用户需求. 在这一课中, 你将创建类, 在 problem domain 包中填充一些实际内容 . 本课的某些内容展示了 Together 的 LiveSourceTM 实时同步技术. 这项技术是 Together 的长期特征 , 给使用者留下了深刻印象. 玩得开心! 目录: ƒ 创建新类 ƒ LiveSourceTM 实时同步技术 ƒ 在 Together 外部编辑源代码 ƒ 增加特性(attributes) ƒ 增加操作(operations) ƒ 修改查看设置 ƒ 修改类属性 ƒ 技巧 创建新类 下面是 airline 工程得最初需求. ƒ 预定航班. ƒ 购买机票. ƒ 确定航班上是否还有足够的座位可以预定. ƒ 计算航班的机票收入总数. 从这些需求, 我们可以得到五个类. 下表中列出了这些类及其特性和操作. 这仅仅是一个开始. 继续深入下去, 你将发现需要更多的类和 类成员. 类 FlightDescription ScheduledFlight Reservation Ticket Agent 特性 departureTime arrivalTime origin destination capacity date name basePrice name 方法 getCapacity() setCapacity() makeReservation() numberOfTickets() ticketPurchased() calcPrice() calcPrice() makeReservation() 开始工作前先在 Designer 面板中将 ProblemDomain 包打开. 操作步骤 : 在 ProblemDomain 包中创建五个类: FlightDescription, ScheduledFlight, Reservation, Ticket, 和 Agent. 按 再点击 Designer 工具条中的类按纽( )以便创建多个类. 为类命名, 不需要书写任何类声明 -- Together 会自动生成代 码. 当你在 Designer 面板中创建新 类时, Editor 面板将显示对应的 新代码. 当你回到 模型图, 你将看到 ProblemDomain 包中显示了新建的类. 如果在某个 模型图中进行修改, 则在相关模型 图中也会有对应的显示. 下图是 ProblemDomain 包 节点. 类名旁边的 + 表示类是 public 的. Together 现在在包的物理目录中为类建立了源代码文件. Explorer 面板将把新类作为当前工程的一部分进行跟踪. 注意: 虽然这个工程中没有内部类(inner classes), 但创建内部类是很容易的. 只需要简单地将一个类拖动到另一个类内部即可. 或者你 也可以在工具条上点击类按纽, 然后在 Designer 面板中的某个外部类上点击鼠标. LiveSourceTM 实时同步技术 Together 使用你的源代码来构建类图. 它不保留类图库. 当你在源代码中进行合法的修改时, 类图也会反映这些修改... 并且反过来也 是如此. 在这一节和下一节中, 我们将向你展示如何修改工程中的部分元素, 以演示 Together 的 LiveSourceTM 技术的工作状况. 操作步骤 : 使用 Designer 面板将 ScheduledFlight 类改名为 Flight. 可以使用类的右键菜单来修改其名称. 或者在 Designer 面板中简单地双击类名即可. Together 将更新代码, 文件名, 和类图. 当你打开 模型图, 请注意 Together 已经更 新了 ProblemDomain 包节点中的类名. 操作步骤 : 在 模型图中将 ProblemDomain 包改名为 AirlinePD. 可以在 模型图中使用 ProblemDomain 包的右键菜单为其重命名. 下图是本操作的结果, 它指出 Together 进行了四 处修改. (Explorer 面板的 Directory 页显示物理目录也被正确地重命名了.) 在 Together 外部编辑源代码 Together 并不强制用户按特定地方式工作. 在你使用 Together 管理你的工程的同时, 你也可以用你喜欢的编辑器编辑你所有的源代 码. Editor 面板右键菜单中的 Tools | External Editor 命令使你可以快速地用外 部编辑器打开源代码文件. 操作步骤 : 用外部编辑器打开 FlightDescription.java 文件. 增加两个 String 类型地成员, origin 和 destination, 然后在 编辑器中保存文件. WinVi 是 Windows 下缺省的外部编辑器. (使用 Tools 菜单, 可以很容易地在工程设置中修改这个选项.) 我们在外部编辑器(WinVi)中打开了 FlightDescription.java 并输 入了 origin 和 destination 的声明. 当我们在 WinVi 中保存源代码文件时 , Together 将更新模型图. Together 还 在它的 Editor 面板中更新源文件的显 示. 当文件时间标记变化时, Together 将更 新它的 Editor 面板和 Designer 面板 的显示. 操作步骤 : 格式化新录入的两行 Java 代码(origin 和 destination 的声明), 使得代码缩进, 而不是向左对齐. Format Source 是 Editor 面板右键菜单中的工具. 执行它将重新格式化 Editor 当前聚焦的源代码, 使得它符合 Editor 设置中的 格式化方案. 下图显示了 FlightDescription.java 格式化前(后图)和格式化后(前图)的内容. 增加特性 为一个类增加成员的快速方便的方法是在模型图中对应的节点上增加. 操作步骤 : 在 Designer 面板中为 Reservation 类增加 name 成员(类型为 String). 要为类增加新的特性, 先选中类节点, 然后从它的右键菜单中选择 New | Attribute. (或者简单地使用快捷键 , Ctrl+A.) 新建的类成员将有缺省的名称(attribute), 类型(int), 和可见度(private). 你可以在模型图节点的内嵌编 辑器中立即修改这几项. (在模型图中选中类成员, 然后点击它, 以激活内嵌编辑器.) 如果你只是输入了一个新的名称就按了回车, 那么只修改名称, 但缺省的特性类型(或者操作的返回类型)和 可见度维持不变. 当然, Together 保持模型图与代码的同步, 自动将声明增加到源代码中. 下图显示了本步在 Editor 面板 中的结果. 下面是在 Designer 面板种为类增加特性的几种方法 . ƒ 如果类中已有特性, 而你想继续增加, 你可以选中特性按 . ƒ 如果类中已有特性, 而你想在类内部复制特性, 你可以在特性的右键菜单中选择 "clone", 然后修改结果. ƒ 如果想在类之间复制特性, 先选中特性, 并在其右键菜单选择 "copy". 然后在目标类的右键菜单中选择 "paste". ƒ 如果想在类之间移动特性, 可以将特性从一个类拖动到另一个类. 当你将特性拖动到一个合法的目标类时, 类的周围将显示光 圈. ƒ 如果想在类之间复制特性, 可以按 然后拖动特性. 你还可以在类内部拖动特性来改变它们的顺序. 操作步骤 : 修改 Reservation 类中 name 特性的属性 . 1. 将初始值设置为 null 字符串. 2. 将 "Requirement description" 设置为 "Last name first". 3. 将 "author" 设置为你的名字. 下图显示了编辑特性的属性可以在代码中生成 Javadoc 注释. 你可以通过类成员的属性查看器修改其属性.(此时注意选 中的是类成员而不是整个类.) ƒ 在属性查看器的 Properties 页设置初始值. ƒ 在属性查看器的 Requirements 页设置 "author" 和 "Requirement description". 完成修改后, 按 +. 这样将保存修改并 关闭属性查看器. 操作步骤 : 在 AirlinePD 的五个类中增加新的特性. 用 Designer 面板, 而不要用 Editor 面板. 1. Agent -- name (从 Reservation 类复制 ) 2. FlightDescription -- departureTime, arrivalTime (下一节中再增加 capacity 特性.) 3. Flight -- date 4. Ticket -- basePrice 如果类节点太小无法显示所有成员, Together 将显示一个垂直滚动条. 你可以拖动类节点的边界以便修改其大小. 也可以从它的右键菜单中执行 "Actual Size" 来为它自动设置 大小以显示所有成员. 希望修改类成员顺序吗? 拖动它们就可以了. 增加操作 增加操作的技术与增加特性一样. 快捷键是 Ctrl+O. 操作步骤 : 在 Flight 中增加一个无返回值的操作, 命名为 makeReservation. 为这个操作设置两个参数: 1. name, 类型为 String, 表示乘客姓名. 2. tKind, 类型为 int, 表示机票类型. 模型图节点中操作的内嵌编辑器可以接受 UML 风格的输入 (名称在前, 类型在后)或者 Java/C++ 风格的输入(类型在前, 名称在后). 下图列出了其区别. 风格 格式 示例 UML name(parameters):type myMethod(myParameter:int):double Java/C++ type name(parameters) double myMethod(int myParameter) 特性缺省的可见度是 "private". 操作缺省的可见度是 "public". 你可以通过模型图节点的内嵌编辑器 , 属性查看器, 或者源代码来修改 类成员的可见度. 操作步骤 : 使用 Designer 面板将 makeReservation() 从 Flight 复制到 Agent 中. 要将操作从一个类复制到另一个类, 可以按 键拖动 . 或者从操作的右键菜单选择"Copy", 然后在目标类的右键菜单选择 "Past". Designer 面板将一个操作从一个类完整地复制到另一个类, 包括方法体. 操作步骤 : 为 Reservation 类增加以下操作. ƒ 构造方法, 包括一个 String 类型参数(name) 和一个 int 类型参数(tKind) ƒ ticketPurchased() 方法, 返回值为 boolean 类型 ƒ calcPrice() 方法, 返回值为 double 类型 类节点地右键菜单包括 New | Constructor 命令, 你可以通过这个命令创建 Reservation 类的构造函数. 你最终将使用到右键菜单的另外两项: New | Property 和 New | Member by Pattern. (右 图显示可以通过右键菜单创建内部类. 你也可以将一个类拖动到另一个类内部来实现.) 修改查看设置 在 Together 的设置中包括类图中显示多少细节的设置. 任务 T: 设置 AirlinePD 模型图的细节级别("detail level"), 以便显示操作中的参数 . 你可以点击 Designer 面板水平工具条中的 "View Management" 按纽( )来设置模型图的细节级别. 将模型图的细节级别设置为 "Implementation" 选项后, Reservation 节点显示情况如 下: 有些设置类别(比如 "View Management") 包含它们本身 的顶级设置. 要访问较低级别的 设置, 你必须先将上级设置展开. 操作步骤 : 将以下操作增加到 Flight 类和 Ticket 类中. ƒ Flight - numberOfTickets() 方法, 返回一个 int ƒ Ticket - calcPrice(). 从 Reservation 类中复制. 如果特性(attribute)拥有对应的 getter 操作和 setter 操作, 则 Together 将其视为属性(property). 操作步骤 : 使用 FlightDescription 的右键菜单增加一个 capacity 属性. 从 FlightDescription 的右键菜单 选择 Property. 当你创建属性后时, Together 还在代 码中创建 getter 操作和 setter 操 作及其方法体. Together 将带有 getter 操作和 setter 操作的类视为 JavaBean. 一个 JavaBean 在模型图中的节点在 左上角有一个小标签. Getter 操作和 setter 操作不显示在操作中 . 并且所 有属性的特性都从特性中移动到节点 底部的属性区域中. 工程设置中包含一个选项可以打开/关闭对 JavaBean 的识别. 五: 类与关联 在前面的课程中, 你已经创建了一些类. 但这只是一个没有关联的简单的类图. 在这一课中, 你将创建连接这五个类的关联来弥补这一缺 陷. You will label some of the associations and put on multiplicities. 在这一课的结尾, 你将创建一个接口和两个子类. 而且你将通过一般化连接 和实现连接 把它们和有的类连接起来 . 目录: ƒ 创建关联 ƒ 修改关联 ƒ 将连接修改为聚合 ƒ 显示继承关系 ƒ 创建并实现接口 ƒ 在模型图中增加便签 ƒ 技巧 创建关联 你将在 AirlinePD 包中工作. 请在 Designer 面板中打开它的模型图. 操作步骤 : 创建从 Flight 到 FlightDescription 的关联. 首先点击垂直工具条中的关联按纽( ). 关联与其他模型 图中的连接元素的工作方式一样. 当你将光标移动到有效 的 client(开始点) 和 supplier(结束点) 时, Together 将在节点周围显示光圈. 将光标从 Flight 拖动到 FlightDescription, 然后释 放鼠标. Designer 面板将新建的关联显示为蓝色线条. 创建关联后, 你将在 Editor 中看到 Flight 类中出现了 名为 lnkFlightDescription 的新的数据成员. 注意 lnkFlightDescription 没有出现在 Designer 面板的 Flight 节点内部. Together 将名称以 "lnk" 开头的特性认为是 "自 动" 连接, 而且它不将这样的特性显示在类节点内 , 除非你修改模型图设置. (如果你希望新建连接成员显示为一个特性 , 你可以将其名称 修改为不以 "lnk" 开头.) 操作步骤 : 创建两个关联: 1. 从 Reservation 到 Ticket 2. 从 Agent 到 Flight Together 允许选择连接的显示方式: ƒ 折线: 连接线显示为一系列水平和垂直线段. ƒ 直线: 连接线是直线, 但可能是倾斜的. (连接线也可以是任意倾斜度的一系列线段). 连接线显示方式在模型图设置中, 可通过主菜单中的 Tools | Options | Diagram Level 命令访问. 大多数连接从一个类到另一个类 . 但有时候可能连接到自身 , 开始点和结束点都在同一个类上 . 你可以在我们的模型图中放置一个自连接 , 以区别航班计划和实际的航班. 操作步骤 : 将连接显示为直线, 然后在 Flight 上画一个自连接. 下图是到目前为止模型图的样子. 修改关联 关联也有自己的右键菜单和属性查看器. 对连接进行的很多修改, 都必须通过右键菜单或属性查看器来实现. 操作步骤 : 为 Flight 到 FlightDescription 的关联设置势. ƒ client 端(Flight)设置为 0..* ƒ supplier 端(FlightDescription)设置为 1 连接的右键菜单的内容根据当前光标位置而变化. 要修改连接的势或者角色, 请在其末尾处点击鼠标 右键. 右键菜单中显示了最常见的势. 大多数时候你可以直接选择, 而不需要在属性查看器进行修改. 操作步骤 : 为从 Reservation 到 Ticket 的连接指定适当的势, 规则如下: 一张机票必须关联到一个确定的预约. 一个预约则可能有对应的一张机票, 也可能没有. 为从 Agent 到 Flight 的连接指定适当的势, 规则如下: 一个代理商可以知道很多航班信息; 一个航班信息也可以提供给很多代理商. 连接的属性查看器中包含了很丰富的菜单可供修改连接. 使用它可以为连接 端分配角色, 也可以使连接成为有方向的. 操作步骤 : 为 Flight 上的自连接的各个端设置势和角色, 并使这个连接有方向. ƒ 将 supplier 端角色命名为 "actual." 将它的势设置为 0..1. ƒ 将 client 端角色命名为 "plan." 将它的势设置为 1. 最后一步操作, 使用 Flight 自连接的属性查看器实现. 将连接修改为聚合 每个 Flight 都拥有一个 Reservations 的集合, 而不是单个的 Reservation. 操作步骤 : 创建一个从 Flight 到 Reservation 的聚合 . 这个操作很简单. 首先创建一个连接, 从 Flight 开始, 到 Reservation 结束. 然后在新建连接的右键菜单中选择中 "Aggregation". 连接将在 Flight 显示一个菱形箭头. 创建新的连接可能会使模型图变得比较混乱. 你可以通过模型图右键菜单(Layout | All)来让 Together 重新排列模型图 . 或者你也可 以直接拖动连接. 当你选中连接时, 光标将显示为十字( ). 移动光标将改变连接的形状. 如果你在连接的末端移动鼠标, 光标将显示为 4 箭头状( ). 此时, 你可以将连接的末端移动到另一个类上. 显示继承关系 你现在可以从 Ticket 扩展出两个实体类, Ticket 是抽象类. 你还将为 Agent 和 Reservation 类创建一个接口. 操作步骤 : 创建一个名为 Coach 的类. 然后完成以下步骤: 1. 用 generalization 从 Coach 连接到 Ticket. 2. 将 calcPrice() 从 Ticket 复制到 Coach. 3. 将 Coach 的策略(stereotype)设置为 "thing." 使用一般化连接按纽( ) 使 Coach 类扩展 Ticket 类. 当你将抽象方法复制到一个实体类时, Together 会在模型图和代码中将其变 为实体方法. 操作步骤 : 将 Coach 类复制一份, 然后重命名为 FirstClass. 要复制一个类, 在模型图的右键菜单中先使用 "Copy" 命令, 然后使用 "Paste" 命令. 除了名字以外, 新类将与旧类完全一致. 所有的 构造函数都被复制为新的名称. 从原来的类开始的所有连接也都被复制了. 并且代码中的所有 Javadoc 注释也都被复制了. 操作步骤 : 整理模型图: ƒ 将连接线设置为矩形线. ƒ 将继承关系显示为水平方式. 为了进行模型图级别的修改, 比如上面的操作, 你需要打开模型图设置窗口: 在主菜单中选择 Tools | Options | Diagram Level. ƒ "将连接修改为矩形线"在模型图设置的最顶级. ƒ "将继承关系显示为水平方式"在 Diagram | Layout 级. 创建并实现接口 最后一个任务, 我们假设 Agents 类和 Reservations 类都可以给出其名称. 操作步骤 : 创建一个接口, 命名为 INamed. 然后完成以步骤 . 1. 为 INamed 增加一个操作, 名为 getName(), 返回类型为 String. 2. 将 Agent 类和 Reservation 类连接到 INamed. 创建接口的过程与创建类和包一样. 使用 Designer 工具条中的接口按纽( )即可. 你可以编辑其名称. 注意 Together 将接口的名称 及其中的操作显示为斜体字. Designer 工具条中一般化按纽( )除了显 示类的继承关系, 还可表示类实现接口. Together 会自动在实现接口的类的声明中 插入 "implements" 部分. 实现接口的类中必须定义接口中的操作. 我们先不在 Agent 类和 Reservation 类中实现 getName(), 这个任务将推迟到讨论设 计模式时再完成. 在模型图中增加便签 你已经基本完成这一课了. 但现在我们再向模型图中增加一种新的元素: 便签, 用来解释预定航班的业务规则: "如果售出的机票数不超过该航班容量, 那么你可以预定航班." 操作步骤 : 在 AirlinePD 类图中放置一个便签, 以便描述业务规则. 然后将便签类型设置为 "business rule". 使用 Designer 面板工具条中的便签按纽( ) -- 直接在模型图上 的便签节点中输入文字. 完成后, 使用便签连接按纽( )将便签连接 到 Flight 类. 你可以在便签属性查看器的 "Requirements" 页中设置便签类型, 如右图所示. (注意我们的属性查看器没有停靠到主窗口中. 点击属性 查看器右上角的图钉按纽将把属性查看器停靠到 Explorer 面板的底 部.) 下图是我们的 AirlinePD 类图目前的样子. 连接线是矩形风格的. 继承关系是水平风格的. 技巧 ƒ 如果你在 Designer 面板右键菜单中选择 Layout | All, Together 将整理模型图的几何排列. ƒ 如果你不喜欢任何一个修改, 不论是移动了模型图元素, 创建或删除了元素, 或者是修改了代码, 你都可以使用撤消按纽. 可以 进行多级撤消. 而且你不想撤消, 你还可以选择重做按纽. ƒ 撤消和重做按纽有提示信息, 描述将要撤消或重做的动作. ƒ 在模型图上创建一个自连接有困难吗? 请把连接线的风格从矩形线修改为直线. ƒ 如果你从一个接口或一个抽象类中将一个方法复制到实体类, 它将被复制为一个实体方法. 如果你从一个类中将一个方法复制到 一个接口, 它将被复制为一个方法声明(没有方法体). ƒ 如果你希望一个关联显示在类节点中, 将它的名称修改为不以 "lnk" 开始即可. 或者如果你希望所有的关联都显示在类节点中, 你可以从主菜单中选择 Tools | Options | Diagram Level. 然后选择 Diagram | Associations | Show as attributes | All. ƒ 要将所有的连接显示为有方向的, 从主菜单中选择 Tools | Options | Diagram Level, 然后选择 Diagram | Associations | Draw Directed | All. 六: 模板模式 模式是代码重用的一种有效工具. Together 支持两种模式: 模板模式和 "模块" 模式. 模板模式对于单个类以及连接和属性很有用处. 模块模式一般用于更复杂的设计模式, 如 GoF 设计模式或 Coad 类模式. 你可以使用模式来创建新的类或成员. 你也可以将模式应用 到已存在的类和成员中. 这一课主要集中讨论模板模式. 在最后, 我们将演示如何创建你自己的类模板模式. 目录: ƒ 选择类成员模式 ƒ 将模式应用到连接 ƒ 应用类模板模式 ƒ 制作自己的模板模式 ƒ 技巧 选择类成员模式 Together 提供了三种普通的 Java 类成员模式: "Stub Implementations", "Properties", 以及 "Main method". "Stub Implementations" 模式在一个需要返回值的操作中插入虚构的 "return" 语句. "Properties" 模式创建带 getter 和 setter 操作的 特性. "Main method" 模式将一个操作改为 main( ) 方法. 操作步骤 : 将 "Stub Implementation" 模式应用到三个方法: 1. Coach.calcPrice() 2. Reservation.ticketPurchased() 3. Flight.numberOfTickets() 删除 FirstClass.calcPrice(), 因为它有一个空的方法体 , 然后将 calcPrice() 方法从 Coach 复制到 FirstClass. (不要修改 Reservation.calcPrice(). 将这个方法保留到以后实现.) 要应用 "stub" 模式, 首先从操作的右键菜单选择 Choose Pattern. Together 打开一个模式窗口 , 其中列出了成员模式和 连接模式. 编辑器显示结果代码. 操作步骤 : 将 "Property" 模式应用到 Reservation.name 和 Agent.name. 给每个属性一个 get 方法, 但不要 set 方法. 使用特性的右键菜单中来应用 "Properties" 模式. 当你从模式列表中选择 "Properties" 时, 模式窗口的右边允许你修改属性的名称 , 类型以及是否有 getter 方法, 是否有 setter 方法, 是否有特性. 如果你修改了 "Name" 中的文字, Together 将修改特性和方法的名字. 如果你没有选中 "Attribute" 框, Together 将彻底删除特性. 如果你想创建一个新的属性, 而不是使用已存在的特性, 你可以使用类的右键菜单中的 "Member by Pattern" 选项. 将模式应用到连接 左图是 AirlinePD 类图的一部分 , 它显示了从 Flight 到 Reservation 的关联. UML 模型 图只表示这个关联是一个聚合. 模型图没有显示任何实际的实现信息. 聚合代码到底是 collection?, array?, vector?, 还是 hash table 呢? 应该由程序员来选择适当的代码实现. 连接模式提供了一些帮助. 操作步骤 : 将 "Aggregation as ArrayList" 模式应用到从 Flight 到 Reservation 的 连接. 有两种方法应用连接模式: 1. 对于已存在的连接, 在它的右键菜单中选择 Choose Pattern 项. 2. 如果连接不存在, 那么可以使用模式来创建连接. 模式连接按纽( )在 Designer 工具 条中. 对于这两种情况, Together 都会显示 Association Pattern 对话框. 对话框中的模式选择面板列出了很多连接模式. 最后一步, 我们从 java.util collections 中选择 Association as ArrayList. Association Pattern 窗口的 Preview 面板显示了 Together 将要在 Flight 类中生成的代码. (实际代码将包含一个 import 语句, 而不是使用完全标识的 ArrayList 类型名.) 应用类模板模式 现在可以创建一个带 main 方法的 Driver 类了. Driver 类在 UserInterface 包中, 而不是 AirlinePD 包. 在进行下一步前, 先在新的页中打开 UserInterface . 操作步骤 : 在 UserInterface 包模型图中创建一个 Flight 的快捷方式(别名). 首先进入 Explorer 面板的 Model 页. 展开 AirlinePD, 然后打开 Flight 类的右键菜单. 选择 Add as Shortcut. UserInterface 模型图显示 出一个新的节点, 节点左下角 显示一个快捷键符号( ). 操作步骤 : 使用 Main Class 模式创建 Driver 类. 通过工具条中的用模式创建类按纽 ( )完成这一步. (按纽下面的三个点表示这是一个模式按纽 .) 将一个模式类放置到 Designer 面板 中, Together 将显示类似下图的模式窗口. 如图所示, 我们选择 Main Class 模式, 然后在 Parameters 面板的 Name 输入框中将类名从缺省的 Class1 修改为 Driver. Preview 面板显示 Together 将 生成的代码. 这里 Main Class 模式看起来并没有节省多少时间, 但是其他模式可能给你更深刻的印象. 例如, 请看一下 Bean 类模式和 Servlet 类模式. 操作步骤 : 建立一个从 Driver 节点到 AirlinePD.Flight 节点的连接. 然后修改 Driver 的源代码, 将这个连接改名为 myFlight. 最后这一步与模式无关, 而与视图有关. 右图是我们的目前的 Designer 面板和 Editor 面 板. 有两件事情值得注意: 1. 当我们创建连接时, Together 在我们的代码 中加入适当的 import 语句. 2. Flight 节点不显示其中的成员. 在模型图中你可以通过节点的右键菜单隐藏类的成员. 制作自己的模板模式 Java 类模板保存在 Together 根目录下的 templates/JAVA/CLASS 中. 目录下的每个文件夹包含两个文件 : 1. %Name%.java, 模板的源代码 2. FolderName.properties, 用于创建代码和文档的各种属性 Together 有一个代码模板向导, 可用来创建新的模板, 或者修改已有的模板. 向导将为新模板自动创建文件夹并将上述文件生成到文件 夹中. 操作步骤 : 使用模板向导创建一个 SimpleException 模板. 我们通过以下步骤进行: 1. 从主菜单中选择 Tools | Code Template Expert. 2. 在代码模板向导的第一个面板中, 选择: Template Language: Java Template Category: Class 3. 在代码模板向导的第二个面板中: 点击 New Template. 在对话框中输入 SimpleException, 然后点击 Ok, 如下图所示. 4. Together 回到同一个面板中. 从列表中选择 SimpleException. 然后点击 Next 进入第三个面板. 操作步骤 : 填写例外的详细信息, 首先是 "template documentation". 缺省的名称将是 "Exception1". 为对话框创建适当的描述信 息. 在第三个面板中执行以下步骤(继续上面的操作): 1. 第三个面板: 将缺省名称填写为 "Exception1". (除非你输入不同的名称 , 否则这个模板生成的所有新类将命名为 "Exception1".) 2. 第三个面板: 填写 "Template description", 这将是 "Exception" 模板被选中时对话框中的文档信息(描述是 HTML 格式 的.) 下图是我们的代码模板向导此时的样子. 操作步骤 : 填写模板定义, 完成模板. 1. 在第三个面板中点击 Edit Template Code 按纽, 显示填写代码的窗口 . 2. 填写如下图所示的代码. 你可以点击 %Name% 按纽, 而不必手工输入 6 个字符. (当使用模板时, %Name% 宏将被替换为 Name 中的文字 .) 3. 输入代码后点击 Format Source . 4. 当你希望完成代码时点击 Ok. 5. 在下一个面板中点击 Finish 完成操作. 操作步骤 : 在 AirlinePD 包中创建一个 Exception 类, 命名为 ReservationException. 回到 AirlinePD 包. 在模型图工具条中点击用模式创建类 按纽( ) , 然后点击模型图 . 选择 SimpleException 模式. 前面工作的结果将显示在模式 对话框中. "Description" 面 板中包含来自属性文件的 HTML 描述信息 . 在右上角的 "Name" 中输入 名称: ReservationException. Preview 面板显示 Together 将生成的代码. 完成后, 新的 ReservationException 节点显示在模型图中. 注意 Together 已经包含了 Std Exception 模式. 它与我们创建的模式只有文档不同 . 我们建议在这个练习中最后创建一个意外, 目的是为了符合活动图中描述的业务规则. 当预定航班的请求因为航班已满而被拒绝时, Flight.makeReservation() 可以抛出一个 ReservationException. 技巧 ƒ 使用工具条从模板中创建类与使用已存在的类或接口的右键菜单是一样的. 使用右键菜单, Together 通常可以根据已存在的代 码来填写名称. (使用 Designer 工具条创建类, 接口, 包, 或者模板类与使用 Designer 右键菜单完全一样.) ƒ 快捷方式就是别名. 你可以从模型图中删除快捷方式, 方法是选中它然后按 键. 如果你通过快捷方式的右键菜单进 行删除, Together 将删除相应的文件(不仅仅是快捷方式). ƒ 创建新的连接模板或者修改已存在的连接模板都是很简单的, 和创建类模板一样. 代码模板向导将引导你完成工作! 只需要在向 导的第一个面板中选择连接即可, 而不是类. ƒ 模板名称(比如 Std Exception)不是类名. 模板名称可以包含空格. 七: 使用类模式进行代码重构 在前面的课程中, 我们讨论了模板模式. 现在我们来考虑一下更复杂的模块模式. 我们主要讨论抽象工厂模式(Abstract Factory pattern), 它是 Together 附带的 GoF 模式的一部分. Together 中的模式对于自动创建哪些难于用手工书写的代码是非常有用的. 而且它们对于重新组织和构造代码也是非常主要的. 这也就 是这一课中你将要使用模式的方式. 但是, 我们首先要进行一些未完成的工作, 对我们唯一的业务规则编写代码. 目录: ƒ 编写业务规则代码 ƒ 使用 GoF 模式重构代码 ƒ 对模型图和代码进行最后的修正 ƒ 技巧 GoF 是 "Gang of Four" 的缩写. 它的意思是: Eric Gamma, Richard Helm, Ralph Johnson, 和 John Vlissides 四人, 他们是著 名的《Design Patterns》和《 Elements of Reusable Object-Oriented Software》的作者. 编写业务规则代码 让我们来编写一些简单的代码, 以便从 Flight.makeReservation() 生成一个时序图. 我们前面的对活动图的讨论中包含了描述代 码的业务规则: 如果售出的机票数不超过该航班容量 , 那么你可以预定航班 . 下面是我们的 Flight.makeReservation() 方法代码. public void makeReservation(String name, int tKind) throws ReservationException { int t = this.numberOfTickets(); int c = lnkFlightDescription.getCapacity(); // Make a reservation only if the number of tickets sold is less than the plane capacity if (t < c) { Reservation r = new Reservation(nam,tKind); lnkReservation.add(r); } else throw new ReservationException(); } 操作步骤 : 完成你的 Flight.makeReservation() 方法代码. 你可以将上面的代码复制到 Together 中. 不过, 不过你手工输入这些代码, 你可能会 看到编辑器的代码感应效果. 右图显示了表达式 lnkFlightDescription 的代码感应效果. 当我们输入 "." 时, 编辑器显示 FlightDescription 的方法列表. 我们简 单地点击方法名即可将方法插入到代码中. Reservation 构造方法还只是一个空方法. 让我们来使用它地两个参数: name 和 tKind. name 参数很简单. 但 tKind 参数需 要考虑一下. 现在只需要简单地按以下方法进行: 如果 tKind 为 1, 创建一个 Coach 类的机票. 如果 tKind 为 2, 创建一个 FirstClass 类的机票. 否则, 不创建机票 . 操作步骤 : 为 Reservation 构造方法填写代码. 下面是我们的 Reservation 构造方法代码. public Reservation(String name, int tKind) { this.name = name; // We will refactor this next piece of code lnkTicket = null; if (tKind == 1) lnkTicket = new Coach() ; else if (tKind == 2) lnkTicket = new FirstClass(); } 使用 GoF 模式重构代码 现在航空公司工程需要进行大的扩展了. 确定机票类型的代码目前完全在 Reservation 构造方法中实现 . 一种很自然的改进方案是将 创建机票的代码移动到一个新的对象中: 一个创建机票的类工厂对象. 在这一课中, 你将建立一个 TicketMaster 类用来创建实际的 Ticket 类. GoF 模式集合中的抽象工厂模式将完成这种困难的工作. 操作步骤 : 应用 GoF 模式集合中的抽象工厂模式 . 名为 Abstract Factory, Concrete Factory, 以及 Abstract Product, 如 下: ƒ ICreateTickets 接口应用 Abstract Factory 模式 ƒ Ticket 类应用 Abstract Product 模式 ƒ TicketMaster 类应用 Concrete Factory 模式 选择 Designer 工具条中的使用模式创建类 按钮( )然后点击 Designer 面板. 此时将出现一个模式选择对话框, 它的左侧是一个模式 选择面板. 展开 GoF 文件夹可以看到 11 个模式选项. Abstract Factory 是 GoF 模式列表中的第一个. 在对话框的右上面板中输入使用模式的类的名 称. 你必须直接输入 ICreateTickets 和 TicketMaster, 因为它们还不存在 . 不要输入 Ticket, 我们使用 Abstract product 文本框右侧的选择框( )来选择 这个类. 操作步骤 : 将 Product 分配为 Ticket 类并完成模式的创建. 首先点击模式选择对话框底部的 Next 按钮. 下一个模式窗口包括一个文本框用于输入 product. 点击其中的选择框将出现类选择窗口 , 类似下图所示. 要选择 product, 首先展开 Model, 然后展开 AirlinePD. 然后选择 Ticket 类, 并点击 OK 按钮. 点击 Finish 按钮完成模式创建工作. 对模型和代码进行最后的修正 创建一个模式可能使得模型图变得比较混乱, 如果这个过程中产生了新的类或者接口尤其如此. 你的模型图现在包括几个新的依赖以及 TicketMaster 类和 ICreateTickets 接口. 操作步骤 : 重新排列 AirlinePD 模型图以便显示整个模型 . 这一步很简单. 打开模型图的右键菜单并选择 Layout | All. 下图是 Explorer 面板的 Overview 页. 右图是对应的 Designer 面板. (我们的连接显示为矩形线.) 此时代码已经基本完成了, 但还没完全完成. 记住我们最初的目标: 重构代码, 将创建 Ticket 类的代码从 Reservation 类移动到 TicketMaster 中. 下面是下一个任务的描述 . 操作步骤 : 修改 ICreateTickets 的操作, 接受一个 int 类型参数; 在 TicketMaster 类中进行对应的修改 . 这是两个简单的小步骤: 1. 使用内嵌编辑器修改 ICreateTickets 中的操作, 如下: createTicket(tKind:int):Ticket 2. 按 键并将操作从 ICreateTickets 拖动到 TicketMaster. 删除原来的无参数的 TicketMaster.createTicket() 方法. 操作步骤 : 将 Ticket 的创建代码从 Reservation 移动到 TicketMaster 并修正语法错误. 你可以在 Editor 面板中通过剪切和复制来移动代码 . 但是移动后的代码不能立即编译. 你需要进行两个小修改 -- 在方法开始处声明 一个 Ticket 类型变量并在结束处返回它. 我们将 Ticket 类型变量改名为 t (原来是 lnkTicket), 如下所示. public Ticket createTicket(int tKind) { Ticket t = null; if (tKind == 1) t = new Coach() ; else if (tKind == 2) t = new FirstClass(); return t; } 对意义重大的常量 1 和 2 进行文档描述是个很好的主意(或者更好的方案是完全消除它们). 但是我们把这个决策留给你决定. 操作步骤 : 完成 Reservation 构造方法, 使它通过一个 TicketMaster 创建适当类型的 Ticket. 下面是我们的新代码, 改造后的 Reservation 构造方法 . public Reservation(String name, int tKind) { this.name = name; TicketMaster tm = new TicketMaster(); lnkTicket = tm.createTicket(tKind); } 操作步骤 : 编译代码以便检查工作结果. 修正所有的语法错误. (如果有语法错误的话 , 应该是比较小的错误.) Make 和 Build 命令在主菜单中的 Project 下, 也在主工具条中. 你也可以在 Message 面板的 Builder 页 中找到这些命令. 编译的输出结果显示在 Message 面板中 . 如果你的代码有错误, 点击错误信息可在编辑器中将错误的代码高亮显示. 继续本课程前请确保修正了你的代码中 的错误. 技巧 ƒ 对于这个工程还有还有其他适用的 GoF 模式. 例如, Composite 模式是一种简单的方法, 可用来支持团体或个人预定航班. ƒ 可以在 Designer 面板种同时选择多个类, 方法是点击鼠标左键并画一个矩形接触到这些类. 当它们被选中后, 你可以成组的 移动他们. ƒ 按 键并拖动操作操作, 可将操作从抽象类或接口中复制到实体类. Together 将使复制的操作成为实体方法. ƒ 使用 Designer 面板可以在编辑器中浏览代码. 例如, 如果你希望将语句从一个方法复制到另一个方法, 首先在 Designer 中 点击方法浏览源代码. 然后复制代码. 然后通过 Designer 浏览到目标方法并复制即可. 八: 时序图 类图给出了模型的整体结构. 但类图是静态图, 与模型的行为无关. 在这一课中, 你将创建一些时序图来描述行为是如何发生的. Together 能从实际的代码中生成时序图. 它也能从时序图生成代码, 包括: ƒ 类声明. ƒ 操作声明. ƒ 方法体. (只在明确需求时才生成 .) 这一课包括生成代码和时序图. 在结束时我们将讨论如何创建超链接来连接相关的工程实体. 目录: ƒ 创建一个时序图草图 ƒ 将一般对象关联到类, 将一般消息关联到操作 ƒ 在模型图中放置控制代码 ƒ 从模型图实现代码 ƒ 从代码生成模型图 ƒ 超链接工程元素 ƒ 技巧 创建一个时序图草图 首先打开 AirlinePD 模型图. 你的第一个时序图将用来描述问题域中的活动. 操作步骤 : 在 AirlinePD 包中, 创建一个名为 FindRevenue 的时序图 . 要创建一个新的模型图, 点击 Designer 工具条中最左边的按钮( ). 下面是我们的新模型图对话框. 我们要填写模型图名称和描述. 时序图工具条中包含五个按钮用于创建模型图. 角色 可以开始消息链 对象 接受和发送消息 ƒ 消息 连接对象 ƒ 自消息 调用同一个对象中的方法 ƒ 语句块 控制语句(循环语句等) 操作步骤 : 在时序图最左侧放置一个角色. 然后放置三个对象. ƒ Together 在除了角色之外的每个对象下方显示一个点状的生命线, 角色下放显示一个窄的矩形条. 操作步骤 : 创建一个从角色到 Object2 的消息. 你可以将消息从一个生命线拖动到另一个. 类似于在类图中拖动一个类关联以及在活动图 中拖动一个转换. 完成这个操作后, 目标对象的生命线中将出现一个(矩形)活动条, 活动条开始于箭头处. 活动条可以拉长, 缩短, 也可以在生命线中移动 . 当你把光标移动到合法的源生命线和目标生命线时, Together 将在其周围显示一个光圈 . 操作步骤 : 创建一个从 Object2 到 Object3 的消息. 确定你创建的这个消息在活动条内部而不是在其下 方. 否则将会在 Object2 的生命线中出现一个新 的独立的活动条. 右图显示了时序图中严格的一般类和一般消息, 它 们与类图中的对象和操作完全没有关系. ƒ ƒ 将一般对象关联到类, 将一般消息关联到操作 ƒ 你可以将一般对象转换为一个已存在的或者新建类的实例. 你也可以将一般消息转换为这些类中的实际操作. 操作步骤 : 从左到右, 为时序图中的对象选择对应的类(除了角色以外): ƒ 对 Object2, 选择 Flight ƒ 对 Object3, 选择 Reservation ƒ 对 Object4, 选择 Ticket 然后将最右边的对象(Object4)改名为 lnkTicket. 通过对象右键菜单完成这个步骤. 右图显示了 Object2 的右键菜 单. Choose Class 中列出了时 序图所属的包中的类. (底部的 More 可用来选择包外部的类 .) 当你选择类后, 你的时序图将把三个对象及其活动条 显示为粉红和绿色策略. 修改对象名称的最简单方法是使用内嵌编辑器. 顺便提一下, 对象右键菜单给出了创建新的类或接口的选项. 如果你 选择了这些选项, Together 将生成相应的代码, 并修改所有相关的 类或包的模型图. 操作步骤 : 为从 Flight 到 Reservation 的消息选择 calcPrice() 方法. 消息也有右键菜单. 其中的 Choose Operation 选项列出了可用的类方法. 操作步骤 : 使用消息的属性察看器为从角色到 Flight 对象的一般消息创建一个新的操作 -- ticketRevenue():double. Properties 选项(消息属性察看器)在消息右键菜单中接近顶部的位置. 当你在属性察看器中指定一个新操作时, Together 显示类似下图的对话 框. 对我们的问题, 你应该点击 Create 按钮. 如果你对已存在的方法改名, Together 的对话框将包含三个按钮: Rename, Create, 和 Cancel. ƒ Together 为时序图提供了显示设置. 从主菜单中选择 Tools | Options | Diagram Level 打开显示设置. 我们的设置如 下. ƒ 我们在模型图中显示消息编号. 你可能希望简化你的模型图, 那么可以不选中 Show message numbers 选项. ƒ ƒ 在模型图中放置控制代码 ƒ 在这一节中, 你将修改 Reservation 生命线中的活动条, 以表现如何从预定一个航班中计算收入: ƒ "如果已售出机票, 农民预定一个航班的收入等于机票价格, 否则收入等于 0." 操作步骤 : 在 Reservation 的生命线的活动条中放置一个自消息. 为这个消息选择 ticketPurchased() 方法. 将返回值命名为 hasTicket. 时序图在 Designer 面板工具条中包含自消息 (self-message)按钮( ). 当你创建自消息后 , 选择 ticketPurchased( ) 作为它的操作 . 对于剩下的操作, 你需要使用消息属性察看器. 属性察看器 Link 页中的 "return" 用于设置返回值的 名称. Together 使用这个名称来产生代码. 在我们的任 务中, Together 产生的代码如下: boolean hasTicket = this.ticketPurchased(); ƒ 操作步骤 : 在 Reservation 生命线的活动条中创建两个语句块.  在自消息下的活动条中放置一个 if 语句. ƒ 将 if 条件设置为 hasTicket.  在 if 下放置一个 else 语句. 点击语句块按钮( ), 然后点击 Reservation 的活动条, 将 出现下图中的对话框. 语句块(例如 if 语句)是活动条中的一个暗色的矩形块. 语句块有右键菜单. 使用属性察看器来设置 if 条件. 条件在 "statement expression" 文本框中. 操作步骤 : 从 if 块到 Ticket 创建一个 calcPrice() 消息. 将返回值命名为 cost. ƒ 语句块, 活动条, 以及生命线痘可以是消息的起点和终点. 在这一步中, 注意将消息起点放置在 if 内而不是活动条中的其他位 置. 消息的 return 属性指定保存操作返回值的变量的名称. 你可以 通过消息属性察看器来设置它. 下图是 Reservation 的活动条 . ƒ ƒ 从模型图实现代码 ƒ 如果方法体中没有代码, 则 Together 可以使用时序图为方法生成代码. 开始下一步骤之前, 请先删除你放置在 Reservation.calcPrice() 方法体中的所有的 return 语句(和所有其他语句). 操作步骤 : 实现 Reservation.calcPrice() 方法. 这是一个很简单的操作. 先删除 Reservation.calcPrice() 方法体中的 代码, 然后从消息的右键菜单中选择 Generate Implementation 即可. ƒ 下图是已完成的时序图, 包含三个粗体字的消息. Together 时序图将执行 Generate Implementation 后生成或修改的 代码显示为粗体 字. ƒ 时序图可以给出代码结构. 但完成详细代码是程序员的工作. 下面是 Reservation.calcPrice() 方法中未完成的代码. public double calcPrice(){ // message #1.1.1 to this:AirlinePD.Reservation boolean hasTicket = this.ticketPurchased(); if (hasTicket) { // message #1.1.2.1 to lnkTicket:AirlinePD.Ticket double cost = lnkTicket.calcPrice(); } else { } } ƒ 你可以使用两个 return 语句来修正这些代码:  在 if 语句块内放置一个 return 语句: return cost;  在 else 中放置一个 return 语句: return 0; 操作步骤 : 在 Reservation.calcPrice() 方法和 Flight.ticketRevenue() 方法中修正语法错误 . 按照你认为合适的方式修正 逻辑错误. ƒ ƒ 从已存在的代码生成时序图 ƒ Together 可以从已存在的没有语法错误的代码中生成时序图. 为下一个任务做准备, 你应该先编译工程以便检查语法错误. 操作步骤 : 从 Flight.makeReservation() 方法生成新的时序图 . 显示来自 AirlinePD 包的所有类 . 但不显示来自 java.util 的类. 生成时序图的命令在类图中操作的右 键菜单中. 右图显示了 Flight.makeReservation() 右 键菜单的一部分. 生成时序图向导给出了显示哪些类和 实现细节的选项. 对于我们的时序图, 我们取消所有的 java.util 项目; 并 选中所有的 AirlinePD 项目. ƒ 下面是我们的时序图. 它的(缺省的)名称是 Flight.makeReservation(1). 亮的矩形是活动条 (对应于方法调用). 暗的矩 形对应于循环或条件语句. 最后的五个对象在图中显示为较低的级别, 表示它们是在活动内部被创建的. ƒ 操作步骤 : 从 Flight.makeReservation(1) 生成一个协作图 . ƒ 协作图与活动图在逻辑上是等价的. 要把它们从一个切换到另一个, 使用模型图的右键菜单即可. (Together 对这两个模型图只 保持一个文件, 只是将同样的信息表现为不同的形式.) 时序图右键菜单 协作图右键菜单 ƒ 下面是我们的 Flight.makeReservation(1) 的协作图. (我们调整了节点位置, 以便在比较小的空间内显示.) ƒ ƒ ƒ 超链接工程元素 ƒ 在 Together 对象之间(比如模型图和模型图元素)建立超链接可以将对象连接在一起, 也便于浏览工程. 如果模型图中的一个 对象有一个到其他对象的超链接, 那么它的名称将显示为蓝色. 当你从一个操作生成一个时序图时, Together 自动建立一个从操作到时序图超链接. 看一 下 AirlinePD 模型图中的 Flight. Flight 中名为 makeReservation 的操作将显 示为蓝色, 因为它已经被超链接到了 Flight.makeReservation(1) 协作图. ƒ 你也可以通过对象属性察看器直接建立从一个对象到另一个对象的超链接. 操作步骤 : 建立从 Make a reservation 用例到 (在 MakeReservation 用例图中 ) 以下元素的超链接:  到 Flight.makeReservation(1) 协作图/时序图  到 Request Reservation 活动图  到 AirlinePD 类图中的 Flight 类  到 AirlinePD 类图中的 Agent 类 首先打开 MakeReservation 用例图. 对 Make a Reservation 点击鼠 标右键, 然后进入属性察 看器中的 Hyperlink 页. 对 Element 点击鼠标 右键, 打开元素选择菜 单. 通过它可以选择将要 加入为超链接的项目. 完成后, Make a Reservation 用例将 显示为蓝色字体. 操作步骤 : 通过新建的超链接从 Make a Reservation 用例浏览到 makeReservation(1) 模型图. 你可以通过 Make a Reservation 的右键菜单来使 用超链接进行浏览. (当鼠标处于超链接上方时 , 光标没 有变成我们熟悉的手的形状, 因为可能存在多个可浏览 的目标.) 使用主工具条中的前进箭头( )和后退箭头( )可以在 超链接元素之间向前和向后浏览. 技巧 ƒ 你可以为一个 Together 元素建立超链接, 链接到完全处于 Together 之外的项目. 例如, 你可以将一个用例超链接 到一份需求文档上. ƒ 你完全不必使用属性察看器就可以为元素建立新的超链接. 请看元素右键菜单中的 Hyperlink To 子菜单. ƒ 时序图与代码紧密地联系在一起, 但 Together 只在用户提出需要时才保持代码与时序图同步. ƒ 你可以使用消息的内嵌编辑器修改操作名称, 而不能修改返回值类型. ƒ 要给消息创建一个有返回值的操作, 请使用消息的属性察看器而不要使用右键菜单中第一项. 九: 文档生成 自描述文档代码 似乎是一种自相矛盾的说法. 但是使用 Together, 自描述文档工程已经成为现实. Together 可以生成文档 -- 所有类 型的文档, 从 HTML 到 RTF 到 PDF. 文档完全是超链接的, 以便显示工程中的对象关系. 对于需要定制特定格式文档的用户, Together 提供了功能强大的文档设计器. 在这一课中你将学习如何生成文档. 我们的讨论很简短, 部分原因是因为生成文档是非常简单的. 目录: ƒ 生成 HTML 文档 ƒ 生成 RTF 格式文档 ƒ 技巧 生成 HTML 文档 Together 使用代码中的 Javadoc 注释来跟踪模型和模型元素的属性. 这些 Javadoc 注释也用来创建文档. 操作步骤 : 为整个 airline 工程生成 HTML 文档. 生成 HTML 文档是很简单的. 从 主菜单中选择 Project | Documentation | Generate HTML . 在对话框中, 将范围设置为 All 并 确认所有的选项都设置被选中. 使用对话框底部的 Options 按钮, 你可以指定很多设置: 1. 包含或不包含标题标记信 息(作者, 版本等等.) 2. 特定的 HTML 选项(窗口 标题, 风格等等.) 3. 文档中显示类的可见度级 别 下图是生成的文档. 浏览器将文档显示为三个框架. 顶部框架是模型图. 左下框架是一个包含 explorer 页和 overview 页的 applet. 右下是书写的文档. Together 生成的 HTML 文档是完全超链接的. 顶部框架是图像映射的. 点击一个方法, 类 或关联都会在右下框架中显示出它们的描 述文档. 移动 Overview 页中的矩形将对应的移动模型图图像; 点击 Project 页中的元素将在右边显示它的文档 . 生成 RTF 格式文档 Together 可以生成几种格式的文档: text, HTML, PDF, 和 RTF. 操作步骤 : 为整个 airline 工程生成 RTF 文档. Together 有一个 RTF 文档的模板, 可以通过主菜单访问: Project | Documentation | Generate using Template. 对话框类似下图. 下面是 Together 为我们生成的 RTF 文档(共 27 页)中的最开始部分. 文档目录超链接到对应的小节. Together ControlCenter l 允许你创建自 己的文档模板. 请看主菜单中的 Project | Documentation | Design Template. 右图是文档设计器中新建立的模板. 使用文档设计器, 你可以指定页眉, 页脚以 及文档内部的组织. 操作步骤 : 如果你有 Together ControlCenter, 为整个 airline 工程生成 PDF 文档. 从主菜单中选择 File | Print Documentation, 将会弹出一个对话框以便创建 PDF 文件. 对话框中包含一个很方便的预览按钮 . 技巧 ƒ Together 使用属性察看器中的很多项目来生成文档. ƒ 当你需要选择文件或文件夹时, Together 将显示"选择文件夹" 图标( ). 点击它可以访问文件系统. ƒ 超链接并不只限于 HTML 文档. 它也时 RTF 文档的组成部分. ƒ 单独被打印的模型图也是文档的一种. 你可以修改模型图设置以便察看分页位置. 在设置窗口中点击模型图, 然后选中 Show page borders. 如果在模型图右键菜单中选择 Layout | All for Printing, Together 将自动排列模型图元素, 同时尽量 避免元素被分割到不同的打印页中 十: 审查与统计 Together 提供了一些特性用于帮助用户强制执行公司标准和惯例, 获得真实的代码统计, 并改进质量. 有两个特性专门设计用于质量保 证: 审查和统计. 审查(Audit)用于检查代码是否符合用户自定义的风格和标准. 统计(Metric)用于计算代码复杂度. Together 对于 Java 工程长期支持审查和统计. 从 Together 5.5 开始, 对于 C++ 和 VB6 也支持统计了. 这一课的讨论基于 airline 工程. 作为一个更丰富的例子, 请打开 Together 附带的 Cash Sales 工程. 目录: ƒ 审查你的工程 ƒ 修正审查错误 ƒ 生成工程统计 ƒ 技巧 审查你的工程 Quality Assurance 是 Together 的可激活特性. 要激活它, 请从主菜单中选择 Tools | Activate/Deactivate Features; 然后 将 Quality Assurance 选中. 从 airline 工程中的 包开始, 执行以下操作. 操作步骤 : 对 airline 工程生成完整地审查. 当 Quality Assurance 激活后 , 你可以在主菜单中选择 Tools | Audits 来访问它. (如果你想对包生成审查, 而不是对整个工程, 请 在包的模型图中点击鼠标右键并选择 Quality Assurance | Audits.) Together 显示一个对话框用于选择审查标准. 对于 airline 工程的审查, 点击 Select All 按钮. (你可以通过 Load Set 按钮载入审查项目集 , 包括对于 Java 的 Sun 代码惯 例.) Java Audit 窗口中最右边的列允许你选中或不选中某个审查项. Java Audit 窗口的右上部分允许你将标准级别设置为低 , 中, 或高. 你 可以按这些级别对审查结果排序. Java Audit 窗口的底部是每种审查标准的文档信息. 对于大多数审查项来说, 文档中显示了违反标准的代码例子以及符合标准的等价代 码. 为 airline 工程生成审查是很迅速的. Together 将审查结果以表格形式显示在 Message 面板中. ƒ 点击任何一列的标题, 这样将使表格按这一列中的内容排序. ƒ 点击任何一项表格内容, 这样将显示它的右键菜单. 每项表格内容的右键菜单中都包含了对它的表述. ƒ 双击任何一行, 这样将在编辑器中显示对应的代码. 上图中选中的审查项指出 import 语句不够明确 : import java.util.*; 我们在代码中插入了 import 语句, 以便 Flight 类可以使用 Date 类型的变量实例. 修正审查错误 对于审查结果表中所有可修正的错误, Together 在最左列中显示一个 F. 上图中的前四个审查错误是可以修正的 . 操作步骤 : 修正你的工程中可修正的审查错误. 审查结果表中的行, 列, 单元格都有右键菜单 . 当你对可 修正的审查错误点击鼠标右键, Auto Correct 将出现在 菜单中. 选择该项后显示的对话框解释了错误的原因和在代码中的 位置. 你可以选择修正单个的错误或者修正多个错误. 下图显示了审查结果窗口和代码文件中的变化. 审查结果窗口对已修正的错误显示绿色对勾. 编辑器中显示了替换代码: import java.util.Date; (替换了原来的 import java.util.*;) 操作步骤 : 从审查结果表生成一份 HTML 文档. 当你对审查结果表点击鼠标右键, 你可以在菜单中选择 Export. 对这一步, 选择 Export | Entire Table. Together 显示一个对话框, 以 便选择文件名称和类型. HTML options 包含一个选项, 可以自动启动浏览器阅读产生的 HTML 文件. 生成工程统计 你可以从 模型图开始下一步 . 操作步骤 : 为 airline 工程生成全部统计. 统计与审查在同一个菜单. 从主菜单中选择 Tools | Metrics. 出口类似下图. 在左上部分是可用的统计项目列表. 对于这一步, 点击 Select All 按钮即可. 右上部分的面板允许你选择每个统计项目 的上限和下限. 间隔尺度(Granularity)可以应用到包 , 类, 或操作中. 下部分的面板是每个统计项目的文档. 结果表显示在 Message 面板中 , 与审查结果表类似, 其中行表示包和类, 列表示统计项目. 列头有提示信息, 表示统计项目的全称. 操作步骤 : 找到 Fan Out 项目的描述信息. 为 airline 工程生成一个 Fan Out 项目的条形统计图. 统计结果表的行, 列和单元格都有右键 菜单. 每列的右键菜单中包含 Show Description 命令, 用于显示统计项 目的文档信息. 描述信息对话框包含两页, 一个是对统 计项目自身的描述, 另一个是条形统计 图. 操作步骤 : 为 airline 工程的以下统计项目重新设置上下限. ƒ CBO -- Coupling Between Objects -- (上限 = 4) ƒ NOC -- Number of Classes -- (下限 = 30, 上限 = 30). 生成统计结果. 然后为 AirlinePD 生成一个 Kiviat 图. 你必须重头开始设置统计项目上下限. 统 计项目对话框的右上部分面板中包含输 入框用于输入新的上下限. 当你生成新的 统计结果时, 新的结果将保存在 Message 面板的新的 Metrics 页中. 右图显示了我们的 Kiviat 图. 蓝色数字 (我们的图中是 NOC)是 低于下限的项目. 红色数字(CBO, CC, 和 FO)是超过上限的项目. 统计结果表中单元格的右键菜单中包含了统计图选项. 内部单元格 (不在第一列或第一行的单元格) 包括条形图选项, 分布图选项, 和 Kiviat 图选项. Kiviat 图对应于行 (类和包). 条形图和分布图对应于统计项. 对于这一步, 将鼠标移动到统计结果表的 AirlinePD 行内, 然后 在右键菜单中选择 Kiviat 图. Together 将生成统计图, 图中将显 示统计项在包内的分布状况. 技巧 ƒ 使用审查和统计作为代码重构的第一步. ƒ 当你希望察看某个统计项在多个类或包中的分布状况时, 使用条形图和分布图. ƒ 当你希望察看多个统计项在某个类或包中的分布状况时, 使用 Kiviat 图. 十一: 运行和调试 Java 工程 在 Together 教程的最后一课中, 你将学习如何使用 Editor 面板和 Message 面板来编译和调试 Java 代码. 你已经忠实地参照本教 程创建了 airline 工程. 但现在你要放弃它 , 改用更丰富地 CashSales 工程. 在 Windows 平台下, Together 安装并使用 Java2TM SDK ver 1.3 的 javac.exe 最为缺省的编译器. Unix 用户必须安装适当的 Java2 SDK 并将其加入搜索路径中. 对于所有的平台, Together 都提供了完整的 IDE 用于 Java 开发. 目录: ƒ 编译并运行一个工程 ƒ 设置断点并使调试器显示动态效果 ƒ 在调试器下运行 ƒ 设置 watchpoint 并改变程序运行 ƒ 技巧 编译并运行一个工程 作为 airline 工程最后的工作, 你可以在 Driver 类中增加简单的输出语句 . (记得 Driver 类吗? 你可以在 UserInterface 包中找 到它.) 操作步骤 : 将以下语句插入到 Driver.main() 中. System.out.println("Goodbye Airline Project."); 然后编译工程. make 按钮( ) 和 build 按 钮( ) 工程在主工具条中, 也 在主菜单中的 Project 下. 当你 make 或 build 一个工 程时, Together 运行缺省的 Java 编译器和 make 工具. Together 将编译结果显示在 Message 面板中 . 如果有错误 或警告, 你可以点击 Message 内中适当的信息, 直接浏览对 应的错误代码. 编译工程的输出信息将显示在 Message 面板中 . 操作步骤 : 创建一个名为 "vanilla" 的运行配置 , 使用 -classic 虚拟机选项. 这是一个多步操作. 1. 从主菜单中选择 Run | Run/Debug Configurations . 结果对话框显示 当前所有的运行配 置 -- 它们都没有 -classic 选项. 2. 在 Run/Debug Configurations 的结果对话框中, 点击 Add 来创建 新的运行配置. 3. 熟土配置名(我们 将我们的配置命名 为 "Vanilla"). 4. 对于 Select class with 'main' 输入框, 点击浏览按钮 ( ). 5. 点击 UserInterface. Driver. 6. 点击 Ok 完成操 作. 操作步骤 : 在新配置下运行 airline 工程. 当你点击主工具条中的运行按钮( )时, Together 显示一个对话框 , 用于选择运行配置. 你应该选择刚才创建的配置. 右图显示了 我们的配置 列表. Message 面 板提供了一 个简单的控 制台窗口, 它 是 Together 中运行的程 序的标准输 入和输出窗 口. 下图是运行 中的程序. 面 板右侧的页 显示包含 main 方法 的类. 注意 Message 面 板包含几个 页. (你可以 通过页的右 键菜单关闭 它.) airline 工程的所有工作到此结束了. 祝贺你. 你已经学习了很多知识! 本教程中剩余的部分已经很少了. 设置断点并使调试器显示动态效果 操作步骤 : 打开 CashSales 工程. 然后打开 problem_domain 模型图. 在 Explorer 面板的 Directory 页中浏览到 CashSales.tpr: Samples | java | CashSales | CashSales.tpr Together 警告你它必须关闭当前工程才能打开另一个工程. 操作步骤 : 在 CashSaleDetail 类(在 problem_domain 包中)的构造方法的最后一个大括号处设置一个断点. 你需要将构造方法载入到 Together 编 辑器中. 如果你对找到它有困难, 你可以 使用 Designer 面板右下角的 Overview 按钮, 将 CashSaleDetail 滚动到模型图的中间. 然后在模型图中点 击构造方法. 在编辑器中, 点击构造方法的结束大括号 的代码行数字的左侧. 这样将把这一行高 亮度显示为红色并在左侧空白区域显示一 个断点图标. 鼠标点击左侧空白区域将打开和关闭断 点. Message 面板的 Debugger 页中显示所有的断点. (如果该页中没有显示 , 从主菜单中选择 View | Message Pane Tabs | Run/Debug 来修改设置.) 操作步骤 : 设置调试器, 使它在运行工程时显示模型图与代码之间的联系. 进入工程设置或 缺省设置, 展开 Run/Debug. 选中 Animate class diagram during debugging. 当你在动态效果 的调试器下运行 工程时, Together 将滚 动类图, 将你当 前跟踪的方法高 亮度显示. 在调试器下运行 操作步骤 : 使用 Debug 运行配置在调试器下运行 CashSales 应用程序 . 察看编辑器中的断点. 主工具条中有 Run in Debugger 按钮( ). 点击 这个按钮将出现右图中的对话 框. CashSales 的 Debug 运行配置时缺省的选项. 点击 Ok 开始运行. 请耐心等待应用程序启动. 你 必须点击 "Scan" 按钮才能 到达断点处. 当程序运行到断 点处, 编辑器将代码行高亮度 显示为蓝色. 操作步骤 : 在断点处, 察看当前栈结构和 CashSaleDetail.qty 值. 当调试器开始运行时, Debugger 页扩展开以便显示详细的运行时信息 . Debugger 面板的左侧是一个工具条, 你可以通过其中的按钮 控制程序执行, 察看栈和线程, 以及设置各种类型的断点. Frame 页(下图中在最前)显示了到达断点时当前栈的内容. 当代码执行到这一点时, 你可以展开 this 以便察看 CashSaleDetail.qty. 点击 Frame 页顶部的方法名将显示当前线程的运行时刻调用栈. 当工程在调试模式下运行时, 编辑器左侧的空白区域将发生改变. 小的菱形图标( )表示可执行的代码行. 断点图标从未运行( )改变为 正在运行( ). 设置 watchpoint 并改变程序运行 操作步骤 : 在 CashSaleDetail.qty 中设置一个 watchpoint. 然后将 qty 值修改为 47. 当程序运行到断点处暂停时, 你可以设置 watchpoint. 点击 Message 面板最左 侧页面中的 watchpoint 图标( ). Together 显示一个类似右图的对话框. 输入如图所示的表达式. 你可以通过 watchpoint 行中的下拉菜单设置 watchpoint 表达式的值. 首先, 在该行上点击鼠标左键使它高亮度显示为蓝色 . 然后点 击鼠标右键显示菜单. 对于这个练习, 选择 Change Value 集合. 在对话框中输入的 qty 新值. 点击 Message 面板中的继续按钮( ) 继续执行. 右图显示了我们用户界面中的执行结果. 实际运行结果将根据查询到的 项目而有所不同. 技巧 ƒ 对于已编译过的或没有内容可编译的工程, 不要使用 make 按钮. 你可以从主菜单中选择 Project | Rebuild Project 来 强制重新编译. ƒ 你可以通过 Debugger 页中断点的右键菜单来删除断点 . 从调试器列表中选择断点, 点击鼠标右键, 然后选择 Remove breakpoint. 或者, 你可以选择断点并点击删除. ƒ 当程序运行在方法调用处暂停时, 如果 Smart Step 已打开, 点击 "Step into" 按钮( )将跟踪到方法内部. (Debugger 页 中有一个 "Skip classes" 页列出了调试器不会进入的类. 缺省状态下, 这将是标准 Java 类库中的类. 你可以使用 "Skip classes" 右键菜单将更多的类加入到列表中. 这个页中有一个选择框允许你跟踪进入类的内部, 如果它的源代码可用的话.) ƒ C++ 程序员也可以使用 Together 编译他们的代码 . 但是首先, 他们需要将 Together 配置中指定的编译器修改为他们自己 的 C++ 编译器 .
还剩83页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 7 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

openIT

贡献于2013-01-13

下载需要 7 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf