4.0. 练习题&答案

  1. What is the necessary and the most important condition to building into the software the quality of supportability?

    The prior architectural design, conforming to some recognized architectural framework, is such a condition.

  2. Which MVC objects represent user interaction events?

    Controller objects.

  3. Which Core J2EE tier is responsible for establishing and maintaining connections to data sources?

    The Integration tier.

  4. Which PCBMER layer is responsible for establishing and maintaining connections to data sources?

    The Resource layer.

  5. What is the CRC approach used for?

    The CRC (class–responsibility–collaborators) approach is a technique for class discovery.

  6. What are role names used for?

    Role names can be used to explain more complicated associations, in particular *self-*associations (recursive associations that relate objects of the same class).

  7. What does transitivity mean in the context of aggregations?

    Transitivity means that if a subset object C is a part of a subset object B and B is part of another subset object A, then C is necessarily a part of A.

  8. A subclass object may be a legal value for a superclass variable. Associated with that observation is the principle of what?

    The principle of substitutability.

  9. Do use cases have the possibility of representing concurrent flow of control?

    No, they don’t. Activity diagrams can represent concurrent flow of control.

  10. Can activity diagrams be constructed before a class model is developed?

    Yes, they can. This is possible because activity diagrams do not explicitly visualize the classes of objects that perform the actions.

  11. A message can denote an asynchronous inter-object communication. How is such a message called?

    A signal.

  12. What UML modelling technique is most useful for discovering class operations?

    Sequence diagrams.

  13. Do state machine diagrams represent the sequence of state changes?

    No, they don’t. State machine diagrams are not specific about sequences of state changes, even if such sequences may be expected.

  14. Will the state change always occur when the relevant transition to that state has been fired?

    Not necessarily. An entry action may be specified and it will then need to satisfactorily completed before the state change can take place.

//一些概念

  • 什么是需求规格说明?–利用图形和其他形式化模型来说明需求。

  • 模型的种类:状态模型,行为模型和状态变化模型。(state models, behavior models and stste change models)

  • 规格说明文档 (specification document (“spec”))是细化的需求文档,没有改变原本文档的结构,但对内容做了非常大的扩展,对系统的各个方面提供了形式化的描述。

4.1. 体系结构优先权 (Architectural prerogatives)

  • 通常,在规格说明阶段不对系统约束(非功能性需求)(system constraints)做进一步考虑,但是系统约束可以指导和验证建模工作。
  • 系统体系结构决定了系统中相互作用的构件和子系统之间的组织形式。它使系统具有适应性(adaptiveness/supportability)。其中包含了三个子特性:可理解性,可维护性和可度量性(understandability, maintainability and scalability)。
  • 软件建模的重要目标是将构建依赖最小化:随着系统模型增长,系统复杂度会上升。解决方法:限制对象通信。

4.1.1 模型-视图-控制器 (Model-View-Controller)

  • 通常,软件设计师采用自顶向下( top-down approach)的方法,由预先确定的体系结构框架(体系结构元模型)(architectural framework)导出设计。
  • 模型对象: 通常表示数据对象,对应问题域中的业务实体和业务规则。模型对象的变化通过发布者/订阅者技术( publisher/subscriber technique)通报给视图和控制器。为了达成这个目的,模型需要封装出关于业务数据和行为的接口。
  • 视图对象: 表示用户界面(UI)对象,把模型的状态展示给用户,通常一个视图对象对应一个控制器。
  • 控制器对象: 表示鼠标和键盘事件,它赋予鼠标、键盘动作的含义,将其转换为对模型对象的请求。它可以将用户的输入与系统的呈现分离(改变系统的反馈,当用户的操作不变(反之亦然))。

4.1.2 J2EE 的核心体系架构(The Core J2EE architecture)

  • J2EE 分为客户层,表示层,业务层,集成层和 EIS(企业信息系统)层,其中表示层,业务层和集成层包含应用程序构件,客户层和 EIS 层处于应用外围。
  • 用户通过客户层与系统交互。呈现 UI 的过程可以在客户端上,web服务器上,或者应用服务器上执行。
  • EIS 层(资源层) 是长期存在的数据传递系统,例如企业数据库,外部企业系统或者外部 SOA 服务。
  • 用户通过表示层访问应用程序,在基于 web 的应用服务里,表示层由用户界面的代码和服务器端的的代码共同构成(包含了 MVC 中的)视图和控制器。
  • 业务层包含了表示层中未被实现的业务逻辑。它负责确认和执行企业范围中的业务规则和事物( enterprisewide business rules and transactions)还管理着从 EIS 层加载的业务对象。
  • 集成层只负责建立和维护数据源之间的连接。
  • 在该模型中构件见只能通过业务层与集成层通信。
  • 没有严格的等级顺序,可以双向通信,可以进行循环调用。

4.1.3 表示-控制器-bean-中介者-实体-资源(PCBMER)

软件需求分析 第四章:需求规格说明

  • 不是完全线性的——较高的层级可以有多个临近的低层级。
  • 单向依赖,但是通信可以多向进行,但是需要使用依赖最小化技术(如发布者/订阅者协议)。
  • 每个类必须属于六个子系统之一,执行单一任务。
  • 类与类之间的耦合只能沿传递依赖关系存在。

4.1.3.1 PCBMER 的层

  • bean 层,表示用来展现在 UI 上的数据类和储存值的对象,可以是用户输入的,也可以是根据实体类生成的。
  • bean不依赖于其他层,可以通过数据传递,也可以通过信息传递。
  • 表示层: 屏幕和 UI 对象,依赖于bean。
  • 依赖的实现方法:拉模型利用调用方法(信息传递)实现。
  • 拉模型(推拉模型) 利用消息传递及事件处理实现。
  • 控制器表示应用逻辑,相应 UI 请求。
  • 实体层响应控制器和中介者,他保存着代表着业务对象的数据,它由数据库中的数据生成,或者为了被存入数据库而被生成。
  • 中介者 是实体类与资源类的信息传输通道。它管理业务的处理流程,执行业务规则,实例化业务对象并在总体上管理着应用的内存。它的存在有两个主要目的:
    • 将实体类与资源层分离,使二者可以分别变化;
    • 在控制器与媒体/资源层中充当媒介,当控制器不知道自己寻找的资源在内存里还是数据库里。
  • 资源层 与外部资源交互,如数据库,Web 服务和 SOA 等。

4.1.3.2 PCBMER 的原则

  • 优点:
    • 相关性分离;
    • 去除了依赖关系的循环(PEBMER 禁止循环依赖)
    • 稳定性高:只要接口不改变,依赖者(高层级)不会受到低层级改变带来的影响。
  • 其他特性和约束
    • 向下依赖原则(DDP):主依赖结构自顶向下,底层结构更加稳定,应封装好。
    • 向上通知原则(UNP):高层对象充当订阅者,底层的状态改变时,向上发送通知,高层回应通知发出者,完成状态同步。(基于事件处理的异步通信)
    • 相邻通信原则(NCP):每一层只能与与之有依赖关系的层传递信息。在非邻层对象之间的信息传递应当使用委托或转发(前者传递一个自身的引用,后者不用)。相识包可以用来在一些更复杂的情况下将接口集成在一起,进而帮助远程的信息传递。
    • 显示关联原则(EAP):这条原则允许类之间传递信息,而且不只是在 DDP 中的自顶向下单向传递,而是互相有关联的类之间都可以进行信息传递,并可以存在双向的关系。例如,用来验证数据完整性。
    • 循环去除原则(CEP):去除循环。具体方法:将出问题的类放在一个新的层级/包中,然后通过提供一个借口来强制循环中的一条路径通过此接口通信。
    • 类命名原则(CNP):在类名前加上层名做前缀,在接口前加 “I + 层名” 做前缀。
    • 相识包原则(APP):包的对象包括接口,而不是接口所在的对象。这有效地实现了非邻层间的通信。

4.2 状态规格说明( state specifications)

  • 状态规格说明是数据结构的模式。
  • 首先确定实体类。确定应用中有哪些实体类类,这些类应在数据库中可以长久保存。

4.2.1 类建模

  • 进行类建模的过程是增量迭代式的。

4.2.1.1 发现类

4.2.1.1.1 名词短语方法
  • 从文档中的陈述中选取名词短语做候选类,并分为相关类,模糊类和无关类类。
  • 这种方法假定文档是完全且正确的,这不好实现。
4.2.1.1.2 公共类模式方法
  • 通过通用的依据将类分为有用的组。
  • 概念类:大多数人认同并共享的想法,如“Reservation”。
  • 事件类:不占用任何时间的类,如“到达”。
  • 组织类:任何形式的,有目的性的团体。如“TravelAgency”。
  • 人员类:表示由人担任的角色,并不是实际的人。如“Passenger”。
  • 地点类:物理位置,如“TravelOffice”。
  • 另外的划分方式:物理类,业务类,逻辑类,应用类,计算机类,行为类
  • 存在问题:与特定需求的关系松散、名字的含义存在误解。
4.2.1.1.3 用例驱动方法(Use case-driven approach)
  • 通过用例的图像模型,描述和交互模型,补充用例过程中的对象。
  • 自底向下。
  • 依赖于用例模型的准确性和完整性。
4.2.1.1.4 CRC 方法 (class–responsibility–collaborators)
  • 程序员玩卡片,卡片分三栏,上边名字左边职责右边协作者
  • 在执行一个场景时,将类命,赋予的职责和写作者填入卡片,每当需要的服务没有类覆盖,加一个新类。如果一个类太复杂,拆成多个类。
  • 利用类间的信息传递识别类。重点是系统中处理能力的统一部署。
  • CRC 适用于验证其他方法给出的类。也可以确定类的属性。
4.2.1.1.5 混合方法
  • 混合方法的过程可能从中间出发。
4.2.1.1.6 Guidelines for discovering classes
  • 下面的指南适用于发现实体类。
  • 每一个类应当具有明确目的的描述。
  • 每一个类都是一组对象的模板。单例类是不应该存在的,而应该硬编码在程序里。
  • 每一个类应有一组属性,可以有主键,用来推算类的对象数。
  • 类应当与属性区分开,如 Color 和 Car。

4.2.1.2 对类进行说明

4.2.1.2.1 类命名
  • 应遵循体系结构的命名规则。如 PCBMER 中的命名规则。
  • 对于组合名字,每一个字母都大写。
  • 尽可能是单数名词。
  • 应该有意义,从客户的词汇中提取,而不是开发者的。
  • 使用长一点的名字是可以的,但是30个字母就太长了。
4.2.1.2.2 发现和说明类的属性
  • 使用如同streetName,或者street_name的格式。

4.2.2 关联建模(Modeling associations )

4.2.2.1 发现关联

  • 主要关联是类发现过程中的副产品。
  • 事实上,所有含有非基本数据类型的类下的非基本数据类型都应当被单列成类,并与原先的类关联。
  • 进行预演(dry run)可以确定协作路径。
  • 循环关联和循环数据:是不一样的,后者的运行时依赖难以管理,应当去除。下图展示的循环依赖,经常发生且可接受。
    软件需求分析 第四章:需求规格说明
  • 循环的关联不一定是闭包的。也就是至少一个循环是可以被导出的。导出关联是冗余的,但是为了效率有时可以保留。

4.2.2.2 说明关联

  • 应涉及:给关联命名,给关联的角色命名,确定关联的多重性。
  • 关联的角色为关联的类中的属性。
  • 关联的角色命名,习惯上以the开头,如“theOrderLine”。
  • 如果只有一个关联连接着两个类,则无所谓关联名和角色名。
  • 角色名对比较复杂的关联进行说明,特别是自身关联。它代表着,关联对应的类会把这个名字视为属性。
  • 应对多重性进行说明,如果在这里多重性不明确,可以先省略。

4.2.3 聚合及复合关系建模

  • 聚合(Aggregation)和复合(composition)意味着超集和子集间整体与部分间的关系。
  • 提高建模能力的四种聚合:
    • ExclusiveOwns aggregation,存在依赖,传递,非对称,固定。
    • Owns aggregation,存在依赖,传递,非对称。
    • Has aggregation,传递,非对称。
    • Nember aggregation(可以是多对多的)。
  • 具体类继承超类的所有属性。

4.2.3.1 发现聚合与复合

  • “…具有…”,“…是…的组成部分” 包含了聚合与复合的语义。

4.2.3.2 说明聚合与复合

  • UML 将强的聚合叫做复合,包括 ExclusiveOwns 和 Owns。
  • 不强的叫聚合,同 has 和 member。

4.2.5 接口建模

4.2.5.2 说明接口

  • 加上关键字 <<interface>>
  • 一个类使用(依赖)了接口,用指向接口的虚线箭头表示,可以加上<<use>>
  • 一个类实现(提供)了接口,用末端带有三角形的虚线表示 可以加上<<implement>>
  • 实现和使用接口

4.2.6 对象建模

  • 利用对象图说明对象之间的关系。

4.3 行为规格说明

  • 系统的行为,是展示给外部用户的,可以用用例来描述。
  • 计算用活动图建模,对象之间的交互利用顺序图或者通信图。
  • 在行为规格说明中,只对系统的冻结状态的操作视图进行定义。对象状态的变化在状态变更规格说明中描述。
  • 用例模型应与类模型同时交替开发。这里只定义实体类。

4.3.1 用例建模

  • 用例建模与需求是紧密结合的,是功能驱动的。
  • 一个完整的功能 ,应包括
    • 逻辑的主流,直流和备选流。
    • 一个外部可见的功能
    • 一个正交功能(用例可以在执行时共享对象,但是用例之间必须是相互独立的(没有依赖关系))
    • 由一个参与者启动
  • 我们只对功能性需求感兴趣。
  • 一些问题可以促进用例发现:
    • 每个参与者要实行的主要目的是什么?
    • 参与者能访问或修改系统中的信息么?
    • 参与者需要将其它系统中的变更告知本系统么?
    • 应该把系统中意料之外的变更告知参与者么?
  • 用户参与者可以确认参与者用例,除此之外还有系统用例。

4.3.1.1 说明用例

  • 应包含参与者和用例和下面四种关系:
    • 关联
    • 包含 <<include>>
    • 扩展 <<extend>>
    • 泛化
  • <<extend>> 关系表明事件的完成会引发组织或关系信息的改变。

4.3.2 活动建模

  • 活动图表示了程序中的逻辑流。
  • 引起流程结束的外部动作只在异常状态下允许。如果这种中断经常出现,应使用状态机图。
  • 任何带有动词的描述都可以被选作候选动作。
  • 并发线程的发起和会合用同步线段表示。可选线程用分支菱形创建和合并。

4.3.3 交互建模

  • 包含顺序图和通信图。
  • 展示对象间为了完成一个用例,一项活动,一个操作等所需的交互模式。
  • 要求一次迭代完成。
  • 可以用去确定类的操作方法。
  • 可以发现消息序列 (Discovering message sequences)

4.3.4 操作建模

  • 类将一组操作作为服务提供给系统中的其他类,这确定了类的公共接口。只有通过公共接口,对象才能相互合作执行用例。

4.3.4.1 发现类操作

  • 最好从顺序图中发现。顺序图中的每一个信息都有一个操作与之对应。
  • 另一个方法:对象对自己的命运负责(CRUD):
    • 创建
    • 读取
    • 更新
    • 删除
  • CRUD 操作允许其他对象请求:
    • 一个新实例
    • 访问其状态
    • 修改其状态
    • 销毁它自己

4.3.4.2 说明类操作

  • 静态操作需显式声明(操作名前加$)。

4.4 状态变化规格说明

  • 对象的状态由他的属性值决定。
  • 在异常条件下,应对异常情况建模。

4.4.1 对象状态建模

  • 为有价值的类根据动态行为建立状态机图。
  • 有些活动是动态的,有些是静态的。动态的前面加 do/
    • Door is closed
    • do/close the door
  • 状态转换由信号事件(异步)或者调用事件(同步)触发。
  • 还有可能是修改事件和时间事件。
  • 动作入口可以用 entry/ ,动作出口可以用 exit/

相关文章: