• 软件需求分析复习要点


    本文根据华南理工大学软件学院《软件需求分析》课程及相关教材《UML和模式应用》总结,作复习回顾用。

    这门课知识点很杂,重点掌握GRASP和GoF设计模式。


    Chapter. 1 面向对象分析与设计(OOA/D)

    UML是标准的图形表示法。它并不是OOA/D,也不是方法。OOD(以及所有软件设计)与作为其先决活动的需求分析(requirement analysis)具有紧密联系,而在需求分析中通常包含用例(use case)的编写。

    分析(analysis)强调的是对问题和需求的调查研究,而不是解决方案。“分析”要加以限制,说清楚是“需求分析”还是“面向对象分析”。

    设计(design)强调的是满足需求的概念上的解决方案(在软件方面和硬件方面),而不是其实现。“设计”也要加以限制。

    在面向对象分析(object-oriented analysis)过程中,强调的是在问题领域内发现和描述对象。

    在面向对象设计(object-oriented design)过程中,强调的是定义软件对象以及它们如何协作以实现需求。

    需求分析可能包括人们如何使用应用的情节或场景,这些情节或场景可以被编写成用例(use case)。

    面向对象分析的结果可以表示为领域模型(domain model),在领域模型中展示重要的领域概念或对象。领域模型并不是对软件对象的描述,它使真实世界领域中的概念和想象可视化,因此也被称为概念对象模型(conceptual object model)。

    顺序图(sequence diagram,UML的一种交互图)是描述协作的常见表示法。它展示出软件对象之间的信息流,和由消息引起的方法的调用。

    可以用设计类图(design class diagram)来有效地表示类定义的静态视图。这样可以描述类的属性和方法。

    OO设计和语言能够缩小软件构件和我们所设想的领域模型之间的差距,即实现低表示差距(lower representational gap)。

    统一建模语言(UML)是描述、构造和文档化系统制品的可视化语言。UML定义了各种UML简档(UML profile),专用于某些常用主题领域的表示法子集。

    UML表示法的基础是UML元模型(meta-model),它描述建模元素的语义,UML元模型主要对模型驱动架构(model driven architecture, MDA)CASE工具提供商具有影响。

    应用UML的三种方式:作为草图、作为蓝图、作为编程语言。

    敏捷建模(agile modeling)强调了UML作为草图的方式,这也是使用UML的普通方式,而且通常对时间投入具有高回报(一般费时较短)。

    UML描述的是原始图类型,如类图和顺序图。同一种表示法可以用来描述模型的三种透视图和类型:概念透视图、规格说明透视图、实现透视图。

    在UP中,领域模型中的UML框架被称为领域概念(domain concept)或概念类(conceptual class)。领域模型表示的是概念透视图。设计模型中的UML框被称为设计类(design class)。设计模型依据建模者的需要,表示的是规格说明透视图或实现透视图。

    概念类(conceptual class),现实世界中的概念或事务。

    软件类(software class),无论在过程还是方法中,都表示软件构件在规格说明或实现透视图中的类。

    实现类(implementation class),特定OO语言(如java)中的类。


    Chapter. 2 迭代、进化和敏捷

    相对于顺序或瀑布(waterfall)生命周期,迭代和进化式开发(iterative and evolutionary development)对部分系统及早地引入了编程和测试,并重复这一循环。在迭代开发中,我们依赖于短时快速的开发步骤、反馈和改写来不断明确需求和设计。相比之下,瀑布模型提倡在编程之前就预先完成需求和设计步骤。

    软件开发过程(software development process)描述了构造、部署以及维护软件的方式。统一过程(unified process)已经称为一种流行的构造面向对象系统的迭代软件开发过程。Rational统一过程(RUP)是对统一过程的详细精化。

    在UP项目中可以引入XP(极限编程,extreme programming)的测试驱动开发(test-driven development)、重构(refactoring)和持续集成(continuous integration)等实践。

    UP是迭代过程;UP实践提供了如何实施OOA/D的示范结构;UP具有灵活性,可以应用于轻量级和敏捷方法,这些方法包括其他敏捷方法(诸如XP或Scrum)的实现。

    迭代开发(iterative development)是UP和大多数其他现代方法中的关键实践。在这种生命周期方法中,开发被组织成一系列固定的短期(如三个星期)小项目,称为迭代(iteration)。每次迭代都产生经过测试、集成并可执行的局部系统。每次迭代都具有各自的需求分析、设计、实现和测试活动。随着时间和一次又一次迭代的递进,系统增量式地发展完善,因此这一方法也被称为迭代和增量式开发(iterative and incremental development),也称为迭代和进化式开发(iterative and evolutionary development)。每次迭代都产生可执行的但不完整的系统,它不是已经准备好可以交付的产品。直到多次迭代之后,系统才可能合格地用于产品部署。迭代的输出不是实验性的或将丢弃的原型,迭代开发也不是构造原型。其输出是最终系统的产品子集。

    迭代开发的优点:

    • 减少项目失败可能性,提高生产率,降低缺陷率。
    • 在早期环节高风险。
    • 早起可见的进展。
    • 早起反馈、用户参与和调整,会产生更接近涉众真实需求的精化系统。
    • 可控复杂性。
    • 一次迭代中的经验可以被系统地用于改进开发过程本身,并如此反复进行下去。

    大部分迭代方法建议迭代时间在2~6周之间。小步骤、快速反馈和调整是迭代开发的主要思想,迭代时间过长会破坏迭代开发的核心冬季并增加项目风险。时间定量超长的迭代不符合迭代开发的观点。迭代的一个关键思想是时间定量(timeboxed),或时长固定。

    在瀑布生命周期过程中,视图在变成之前定义所有或大部分需求。而且通常于变成之前创建出完整的设计。

    UP提倡风险驱动(risk-driven)与客户驱动(client-driven)相结合的迭代计划。风险驱动迭代开发更为明确地包含了以架构为中心(architecture-centric)迭代开发的实践,意味着早期迭代要致力于核心架构的构造、测试和稳定。

    敏捷开发(agile development)方法通常应用时间定量的迭代和进化式开发、使用自适应计划提倡增量交付并包含其他提倡敏捷性的价值和实践。

    采用敏捷方法并不意味着不进行任何建模;建模和模型的目的主要用于理解和沟通,而不是构建文档;只需对设计空间中不常见、困难和几首的一小部分问题建模和应用UML;不要单独一个人建模;并行地创建模型;所有模型可能是不准确的;开发者应该为自己进行OO设计建模。

    UP可以采纳和应用可适应性和轻量级的精神——敏捷UP。UP是迭代和不断进化的,所以在实现前的需求和设计是不完整的。对于整个项目不应有详细的计划。

    UP项目将其工作和迭代组织为四个主要阶段:

    1. 初始(inception):大体上的构想、业务案例、范围和模糊评估。
    2. 细化(elaboration):已精化的构想、核心架构的迭代实现、高风险的解决、确定大多数需求和范围以及进行更为实际的评估。
    3. 构造(construction):对遗留下来的风险较低和比较简单的元素进行迭代实现,准备部署。
    4. 移交(transition):进行beta测试和部署。

    初始阶段不是需求阶段,而是研究可行性的阶段,在此阶段要进行充分的调查以确定继续或终止项目。细化阶段也不是需求或设计阶段,而是迭代地实现核心架构并解决高风险问题的阶段。

    UP描述了科目(discipline)中的工作活动。科目是在一个主题域中的一组活动(及相关制品),例如需求分析中的活动。在UP中,制品(artifact)是对所有工作产品的统称。

    业务建模:领域模型制品,使应用领域中的重要概念的可视化。

    需求:用以捕获功能需求和非功能需求的用力模型及其补充性的规格说明制品。

    设计:设计模型制品。

    在UP中,实现表示变成和构建系统,而不是部署。环境科目是指建立工具并为项目定制过程,也就是说,设置工具和过程环境。UP的一个关键内涵是,所有活动和制品都是可选的,除了代码。


    Chapter. 3 案例研究

    书上讲了两个案例,没有知识点。


    Chapter. 4 初始不是需求阶段

    想要定义摄像并大致得出所需的预算,就必须研究需求。但是,初始阶段的目标并不是定义所有需求,或产生可信的预算或项目计划。

    初始阶段作为UP的第一个阶段也不需要完成所有需求或建立可靠预算和计划。以上内容在细化工程中逐步完成。

    大多数需求分析是在细化阶段进行的,并且伴以具有产品品质的早期编程和测试。

    一句话概括初始阶段:遇见项目的范围、设想和业务案例。

    一句话概括初始阶段要解决的主要问题:涉众是否就项目设想基本达成一致,项目是否值得继续进行认真研究。


    Chapter. 5 进化式需求

    需求(requirement)就是系统必须提供的能力和必须遵从的条件。

    UP能够包容需求中的变更,并将其作为项目的基本驱动力。如果发现在所谓的UP或迭代项目中,试图在开始变成和测试之前指定大多数或所有的需求(用例等),则意味着并非规范的UP或迭代项目。UP提倡使用一些有效的技巧以获得启示。

    在UP中,需求按照“FURPS+”模型进行分类,这是一种有效的记忆方法:

    • 功能性(functional):特性、功能、安全性。
    • 可用性(usability):人性化因素、帮助、文档。
    • 可靠性(reliability):故障频率、可恢复性、可预测性。
    • 性能(performance):响应时间、吞吐量、准确性、有效性、资源利用率。
    • 可支持性(supportability):适应性、可维护性、国际化、可配置性。

    “+”是指一些复制性的和次要的因素,比如:

    • 实现(implementation):资源限制、语言和工具、硬件等。
    • 接口(interface):强加于外部系统接口之上的约束。
    • 操作(operation):对其操作设置的系统管理。
    • 包装(packaging):例如物理的包装盒。
    • 授权(legal):许可证或其他方式。

    其中某些属性可以统称为质量属性(quality attribute)、质量需求(quality requirement)。一般使用中,需求按照功能性和非功能性来分类。

    UP提供了一些需求制品,关键制品包括:

    • 用例模型:一组使用系统的典型场景。主要用于功能需求。
    • 补充性规格说明:基本上是用例之外的所有内容。
    • 词汇表:定义重要的术语,也包含数据字典(data dictionary)。
    • 设想:概括了高阶需求,这些需求在用例模型和补充性规格说明中进行细化。
    • 业务规则:通常描述了凌驾于某一软件项目的需求或政策。

    Chapter. 6 用例

    用例是文本形式的情节描述,广泛应用于需求的发现和记录工作中。

    参与者(actor)是某些具有行为的事务。场景(scenario)是参与者和系统之间的一系列特定的活动和交互,也称为用例实例(use case instance)。场景是使用系统的一个特定清洁或用例的一条执行路径。用例(use case)就是一组相关的成功和失败场景集合。

    用例是文本文档,而非图形;用例建模主要是编写文本的活动,而非制图。

    UMl用例图可以为系统及其环境提供良好的语境图(context diagram)。

    用例不是面向对象的,编写用例时也不会进行OO分析。

    相对于所讨论系统(system under discussion, SuD)来说,有三种外部参与者:

    • 主要参与者(primary actor):具有用户目标,并通过使用SuD的服务完成。
    • 协助参与者(supporting actor):为SuD提供服务。
    • 幕后参与者(offstage actor):在用力行为中具有影响或利益,但不是主要或协助h参与者。

    详述用例(fully dressed use case)是结构化的,它展示了更多细节,并且更为深入。

    通常用例描述的是对一个软件系统(或硬件加软件)的使用,这种情况下称之为系统用例(system use case)。企业级的过程描述被称为业务用例(business use case)。用户目标级别(user-goal level)是通常所使用的级别,描述了实现主要参与者目标的场景,该级别大致相当于业务流程工程中的基本业务流程(elementart business process, EBP)。子功能级别(subfunction-level)用例描述支持用户目标所需的子步骤。

    用例应该包含满足所有涉众关注点的事务。

    前置条件(precondition)给出在用例中场景开始之前必须永远为真的条件。在用例中不会检查前置条件,总是被假设为真。

    成功保证(或后置条件)给出用例成功结束后必须为真的事务,包括主成功场景及其替代路径。

    主成功场景也被称为“理想路径”场景、“基本流程”或“典型流程”。它描述了满足涉众关注点的典型成功路径,它通常不包括任何条件或分支。

    扩展部分描述了其他所有场景或分支,包括成功和失败路径。扩展部分比主成功场景部分所占篇幅更长并且更为复杂。

    黑盒用例(black-box use case)是最常用和推荐使用的类型;它不对系统内部工作、构建或设计进行描述,它以职责描述系统。

    发现用例的基本过程:

    • 选择系统边界。
    • 确定主要参与者。
    • 确定每个主要参与者的目标。
    • 定义满足用户目标的用例。

    对应用需求分析来说,表示用例的有效级别:老版测试、EBP(elementary business process,基本业务过程)测试、规模测试。

    UP提倡用例驱动开发(use-case driven development),这意味着:

    • 功能需求首先记录在用例中。
    • 用例是迭代计划的重要部分。
    • 用例实现(use-case realization)驱动设计。
    • 用例经常会影响用户手册的组织。
    • 功能或系统测试应当符合用例的场景。
    • 为重要用例的最常用场景创建UI“向导”或快捷方式可以方便执行常用任务。

    Chapter. 7 其他需求

    补充性规格说明(supplementart specification)捕获了用例或词汇表难以描述的其他需求、信息和约束,其中包括系统范围的“URPS+”等质量属性或需求。

    有些需求可以成为系统的质量属性(quality attribute),包括可用性、可靠性等。

    领域规则指出领域或业务是如何运作的,通常称为业务规则(business rule)。


    Chapter. 8 迭代1——基础

    细化(elaboration)是一般项目中最初的一系列迭代,其中包括:

    • 对核心、有风险的软件架构进行编程和测试。
    • 发现并稳定需求的主体部分。
    • 规避主要风险。

    细化阶段是UI出的一系列迭代,在这一阶段,小组进行细致的调查、实现、核心架构、澄清大多数需求和应对高风险问题。

    架构原型(architectural prototype)指的是最终系统的产品化子集,更常见名称是可执行架构(executable architecture)或架构基线(architectural baseline)。


    Chapter. 9 领域模型

    领域模型(domain model)是对领域内的概念类或现实世界中对象的可视化表示,也称为概念模型、领域对象模型和分析对象模型。

    UP领域模型是UP业务对象模型(BOM)的特化,领域模型专注于特定领域。

    在表示层或UI层之下的软件对象层是由领域对象(domain object)组成的——领域对象是表示问题领域空间事务的软件对象,并且与“业务逻辑”或“领域逻辑”方法相关。

    概念类(conceptual class)是思想、事务或对象。

    领域模型不是数据模型,所以在领域模型里,并不会排除需求中没有明确要求记录其相关信息的类,也不会排除没有属性的概念类。

    描述类(description class)包含描述其他事物的信息。

    关联(association)是类的实例之间的关系,表示有意义和值得关注的连接。

    多重性(multiplicity)定义类A有多少个实例可以与类B的一个实例关联。

    属性(attribute)是对象的逻辑数据值。

    领域模型中的属性通常应该是数据类型(data type)。


    Chapter. 10 系统顺序图

    系统顺序图(SSD)是为阐述与所讨论系统相关的输入和输出事件而快速、简单地创建的制品。它们是操作契约和对象设计的输入。

    用例文本及其所示的系统事件是创建SSD的输入。SSD中的操作可以再操作契约中进行分析,在词汇表中被详细描述,并且作为设计协作对象的起点。

    用例描述外部参与者是如何与我们所希望创建的系统进行交互的。在交互中,参与者对系统发起系统事件(system event),通常需要某些系统操作(system operation)对这些时间加以处理。

    UML包含了顺序图作为表示法,以便能够阐述参与者的交互及参与者引发的操作。

    系统顺序图表示的是,对于用例的一个特定场景,外部参与者产生的事件,其顺序和系统之内的事件。所有系统被视为黑盒,该图强调的是从参与者到系统的跨越系统边界的事件。

    系统行为(system behavior)描述的是系统做什么,而无须解释如何做。这种描述的一部分就是系统顺序图。


    Chapter. 11 操作契约

    操作契约使用前置和后置条件的形式,描述领域模型里对象的详细编号,并作为系统操作的结果。领域模型是最常用的OOA模型,但是操作契约和状态模型也能够作为有用的与OOA相关的制品。

    操作契约的主要输入是SSD中确定的系统操作、领域模型和领域专家的见解。

    操作契约的组成部分:操作、交叉引用、前置条件、后置条件。

    可以为系统操作定义操作契约,系统操作是作为黑盒构件的系统在其公共接口中提供的操作。系统操作可以在绘制SSD草图时确定。SSD展示了系统事件,即设计系统的事件或IO信息。

    涉及所有用例的系统操作的完整集合将系统视为一个构件或类,定义了公共的系统接口。在UML中,作为整体的系统可以表示成名称为xx的类的一个对象。

    后置条件(postcondition)描述了领域模型内对象状态的变化。领域模型状态变化包括创建实例、形成或消除管理以及改变属性。后置条件不是在操作过程中执行的活动,相反,它们是对领域模型对象的观察结果,当操作完成后,这些结果为真。

    后置条件三种类型:创建或删除实例、属性值的变化、形成或消除关联。

    后置条件并不总是必要的。在大多数条件下,系统操作的效果对开发者而言是相对清晰的,他们可以通过阅读用例、与专家交流或根据自己的知识对此进行理解。但又是需要更详细和精确的描述。契约正提供了此类描述。

    UML正式地定义了操作(operation):操作是可以调用对象执行的转换或查询的规格说明。在UML元模型中,操作具有特征标记,在这种语境中最为重要的是,与一组UML约束对象关联,这些对象被分类为指定操作语义的前置条件和后置条件。


    Chapter. 12 从需求到设计——迭代进化

    如果遵循UP准则,初始阶段大概要调查10%的需求,从细化阶段的第一个迭代开始进行较为深入的调查。

    需求和面向对象分析重点关注学习做正确的事。后续的设计工作强调正确地做事。


    Chapter. 13 逻辑架构和UML包图

    UML包图可以作为设计模型的一部分,用来描述逻辑架构(LA)。UML包图也可以作为软件架构文档中的视图。其主要的输入是补充性规格说明中记录的架构方面的约束和要点。LA定义了包,包中有关软件类的定义。

    逻辑架构(logical architecture)是软件类的宏观组织结构,它将软件类组织为包、子系统和层等。

    层(layer)是对类、包或子系统的甚为粗粒度的分组,具有对系统主要方面加以内聚的职责。

    OO系统中通常包括的层有:用户界面、应用逻辑和领域对象、技术服务。

    软件架构的定义:架构是一组重要决策,其中涉及软件系统的组织,对结构元素及其组成系统所籍接口的选择,这些元素特定于其相互协作的行为,这些结构和行为元素到规模更大的子系统的组成,以及指导该组织结构的架构风格。

    所有软件架构定义的共同主题是,必须与宏观事物有关——动机、约束、组织、模式、职责和系统之连接的重要思想。

    UML包图通常用于描述系统的逻辑架构——层、子系统、包等。UML包代表命名空间。

    领域对象(domain object)表示问题领域空间的事物,并且与应用或业务逻辑相关。

    层(tier)最初表示逻辑层(logical layer),而不是物理节点。现在这个词被广泛用于表示物理进程节点。架构中的层(layer)表示对系统在垂直方向上的划分,而分区(partition)则表示对层在水平方向进行划分,形成相对平行的子系统。

    模型-视图分离原则:

    • 不要将非UI对象直接与UI对象连接或耦合。
    • 不要在UI对象方法中加入应用逻辑。

    观察者(observer)模式是对该原则的合理扩展,即领域对象只能通过语言给定的接口向视图的UI对象发送信息。


    Chapter. 14 迈向对象设计

    敏捷建模的目标是减少常用图形,建模的目的是为理解和沟通而不是构建文档。

    对象模型有两种类型:动态和静态。静态和动态建模之间具有关系,敏捷建模对此的实践是并行创建模型:花费较短的实践创建交互图(动态),然后转到对应的类图(静态)。

    最常见的静态对象建模是UML类图。UML中支持静态建模的其他制品包括包图和部署图。

    类职责协作(CRC)卡是流行的面向文本建模技术。


    Chapter. 15 UML交互图

    UML使用交互图(interaction diagram)来描述对象间通过消息的交互。交互图可以用于动态对象建模(dynamic object modeling)。交互图有两种类型:顺序图(sequence diagram)和通信图(conmunication diagram)。

    交互图是以下两种更为特化的UML图的统称:顺序图、通信图。

    另一种相关的图是交互总览图(interaction overview diagram),该图为在逻辑和过程流方面相关的一组交互图提供了全景总览。顺序图以一种栅栏格式描述交互,其中在右侧添加新创建的对象。

    通信图以图或网络格式描述对象交互,其中对象可以置于途中的任何位置。

    在UML中,前面交互图示例中的一些狂徒称为生命线(lifeline)框图。其严格的UML定义十分晦涩,但通俗地说,它们表示的是交互的参与者(participant),在某些结构图中定义了其相关部分。

    最开始的消息在UML中称为创始信息(found message)。

    在顺序图中可以使用执行规格条(execution specification bar)来表示控制器(focus of control)。

    为了支持有条件和循环的构造,UML使用了图框(frame),具有操作符或标签和保护信息。

    对集合中所有成员进行迭代的常用算法是向每个成员发送同一条信息。

    交互具体值(interaction occurrence,也称为交互使用,interaction use)是在交互中引用另一交互。交互总览图也包含了一系列引用框图。总览图将这些引用组织为更大规模的逻辑和过程流的结构。

    异步消息调用不等待响应,不会阻塞。

    在自己的执行线程中运行或控制自己的执行线程的实例称为主动对象(active object)。实例为主动对象的主动类(active class)也可以采用这种表示法。

    链(link)是连接两个对象的路径,它指明了对象间某种可能的导航和可见性。链是关联的实例。

    消息的顺序使用顺序编号(sequence number)来表示。


    Chapter. 16 UML类图

    UML用类图(class diagram)表示类、接口及其关联。类图用于静态对象建模。

    UML类元(classifier)是“描述行为和结构特性的模型元素”。

    可以用以下方式表示类元的属性(在UML中也称为结构化特性(structural property)):

    • 属性文本表示法。
    • 关联线表示法。
    • 两者兼有。

    关联的断点可以附加导航性箭头,也可以包含可选的角色名(正式的名称是关联端点名,association end name)来表示属性名称。关联断电还可以附加多重性值。

    任何UML图都可以使用注解符号(note symbol),但在类图中更为常用。

    操作不是方法。UML操作是声明,其中包含名称、参数、返回类型、异常列表,可能的前置和后置条件约束等。

    UML方法(method)是操作的实现。可以使用下列几种方式表示方法:

    • 在交互图中,通过消息的细节和顺序来表示。
    • 在类图中,使用构造型为《method》的UML注解符号。

    当我们使用UML注解来表示方法时,实际上是在同一个图中混合了动态视图和静态视图。

    访问操作是提取或设置属性的操作。

    UML关键字(keyword)是对模型元素分类的文本修饰。

    构造型(stereotype)表示对现有建模概念的精化,并且定义在UML简档(profile)之中。简档是一组相关构造型、标记和约束的集合,其目的是使用UML专用于特定领域或平台。

    特性(property)是表示元素特征的已命名的值。特性具有语义影响。

    在UML中,泛化(generalization)的定义是:普通的类元与特殊的类元之间的分类学关系。特殊类元的每个实例也是普通类元的间接实例。

    泛化与OO编程语言(OOPL)中的继承(inheritance)的意义不一定相同。

    UML中所包含的普通依赖关系(dependency relationship)表示,客户(client)元素了解其他的提供者(supplier)元素,并且表示当提供者有所表示时会对可会产生影响。

    依赖可以视为耦合(coupling)的另一个版本,耦合是软件开发中的传统术语,意为某元素耦合或依赖于另一元素。

    UML提供了多种方法表示接口(interface)实现,包括客户的接口和接口依赖(必要接口)。接口实现(interface implementation)的正式名称为接口实现(interface realization)。

    聚合(aggregation)是UML中一种模糊的关联,不精确地暗示了整体-部分关系。

    组合(composition),也称为组成聚合(composite aggregation),这是一种很强的整体-部分聚合关系,并且在某些模型中具有效用。

    UML约束(constraint)是对UML元素的限制或条件。

    限定关联(qualified association)具有限定符(qualifier),限定符用于从规模较大的相关对象集合中,根据限定符的键选择一个或多个对象。

    关联类(association class)允许将关联本身作为类,并且使用属性、操作和其他特性对其建模。

    主动对象(active object)运行于自己控制的执行线程之上。主动对象的类即为主动类(active class)。


    Chapter. 17 GRASP:基于职责设计对象

    GRASP(General Responsibility Assignment Software Pattern)即通用职责分配软件模式。与其将它们称之为设计模式,不如称之为设计原则,它是站在面向对象设计的角度,告诉我们怎样设计问题空间中的类与分配它们的行为职责,以及明确类之间的相互关系等,而不像GoF模式一样是针对特定问题而提出的解决方案。因此GRASP站在一个更高的角度来看待面向对象软件的设计,它是GoF设计模式的基础。

    GRASP是对象职责分配的基本原则,其核心思想是职责分配(Responsibility Assignment),用职责设计对象(Designing Objects with Responsibilities)。

    在绘图(和编写代码)活动当中,我们要运用各种OO设计原则,如GRASP和GoF设计模式。OO设计建模总的来说,基于职责驱动设计(RDD)所代表的内在含义是考虑怎样给协作中的对象分配职责。

    思考软件对象设计以及大型构件的流行方式是,考虑其职责、角色和协作。

    对象的行为职责包括:

    • 自身执行一些行为。
    • 初始化其他对象中的动作。
    • 控制和协调其他对象中的活动。

    对象的认知职责包括:

    • 对私有封装数据的认知。
    • 对相关对象的认知。
    • 对其能够导出或计算的事物的认知。

    RDD也包括了协作的思想。

    如果以结构化形式对这些问题、解决方案和命名进行描述使其系统化,那么这些原则和习惯用法就可以称为模式。在OO设计中,模式是对问题和解决方案的已命名描述,它可以用于新的语境。模式为在变化环境中如何运用和权衡其解决方案给出建议。

    9个GRASP模式:

    • 创建者(Creater)
    • 信息专家(information expert)
    • 低耦合(low coupling)
    • 控制器(controller)
    • 高内聚(high cohesion)
    • 多态(Polymorphism)
    • 纯虚构(Pure Fabrication)
    • 间接性(Indirection)
    • 防止变异(Protected Variations)

    Creator 创建者:
    问题:由谁去创建某些类
    解决:B应该去创建A,当B满足以下某个条件:
    1、B包含A,或B里有很多A
    2、B记录了A
    3、B跟A关系密切
    4、B拥有A实例化中所需数据

    Information Expert 信息专家:
    问题:为一个对象分配职责的一般原则是什么
    解决:把该职责分配给这样一个类,这个类拥有完成这个职责所必须的信息

    Low Coupling 低耦合
    问题:如何保证设计方案支持低依赖性、低变化影响度、增加可重用性
    解决:设计时始终注重低耦合

    Controller 控制器:
    问题:在领域层,由谁负责首先接受并协调来自UI层的系统操作
    解决:创建外观控制器、用例控制器、会话控制器

    High Cohesion 高内聚
    问题:如何使对象功能专注、可理解、可管理、同时支持低耦合
    解决:分配职责时保持高内聚

    Polymorphism 多态
    问题:如何处理依据类型不同而有不同行为的一类需求
    解决:使用多台操作作为依据类型变化的行为进行职责分配

    Pure Fabrication 纯虚构
    问题:依据一些原则获得的解决方案不合适的情况下,不想违反其他的原则,如何把职责分配给对象
    解决:把高度内聚的职责分配给虚构出来的一个类,这个类在领域模型里没有对应的概念

    Indirection 间接
    问题:若两个对象直接连接,导致耦合太紧,如何解决
    解决:把职责分配给一个中介对象,隔离对象与其他构件或者服务,使它们不产生直接耦合

    Protected Variations 防止变异
    问题:如何做到以系统的局部变化为代价就应对不断变化的需求
    解决:标识出能够预计的变化点或者不稳定点,职责分配的时候创建一个稳定的接口,把它们与系统的其余部分隔离开来

    更详细的介绍


     Chapter. 18 使用GRASP的对象设计示例

    用例实现(use-case realization)描述某个用例基于协作对象如何在设计模型中实现。

    可见性(visibility)是一个对象“看见”或引用另一个对象的能力。

    当存在多个可选设计时,应更深入地观察可选设计所存在的内聚和耦合,以及未来可能存在的进化压力。

    对于所有的情形,常见的设计约定是创建一个初始领域对象(initial domain object)或一组对等的初始领域对象,这些对象首先要创建的软件“领域”对象。


    Chapter. 19 对可见性进行设计

    为系统操作创建的设计描述了对象之间的消息。为了使发送者对象能够向接受者对象发送消息,发送者必须具有接受者的可见性,即发送者必须拥有对接受者对象的某种引用或指针。

    当B作为A的属性时,则存在由A到B的属性可见性(attribute visibility)。当B作为参数传递给A的方法时,存在由A到B的参数可见性(parameter visibility)。当B被声明为A的方法内的局部对象时,存在由A到B的局部可见性(local visibility)。当B对于A是全局时,存在由A到B的全局可见性(global visibility)。


    Chapter. 20 将设计映射为代码

    一对多关系非常常见。在OO编程语言中,这些关系通常使用集合(collection)对象或简单的数组来实现。

    类的实现要按照从耦合度最低到耦合度最高的顺序来完成。

    测试驱动开发(test-driven development, TDD)或测试优先开发(test-first development)是极限编程方法提倡的优秀实践。


    Chapter. 21 测试驱动开发和重构

    在TDD风格的OO单元测试中,要在测试类之前编写测试代码,并且开发者要为几乎所有的产品代码编写单元测试代码。

    TDD的优点:

    • 能够保证编写单元测试。
    • 使程序员获得满足感,从而始终如一地编写测试。
    • 有助于澄清接口和行为的细节。
    • 可证明、可再现、自动的验证。
    • 改变事物的信心。

    重构是重写或重新构建已有代码的结构化和规律性方法,但不会改变已有代码的外在行为,而是采用一系列少量转换的步骤,并且每一步都结合了重新执行的测试。重构的本质是一次实行一小步保留行为的转换,每次转换只有要重新执行单元测试,以保证重构不会导致错误。


    Chapter. 22 UML工具与UML蓝图

    在CASE(计算机辅助软件工程)工具的领域里,前向工程(forward engineering)是从图形生成代码,逆向工程(reverse engineering)是从代码生成图形,而双向工程(round-trip engineering)是以上两种工程的闭环。


    Chapter. 23 迭代2:更多模式

    在本次迭代中,强调:

    • 基本对象设计
    • 使用模式来创建稳固的设计
    • 应用UML使模型可视化

    在迭代1结束的时候,应该完成以下任务:

    • 所有软件都已经被充分地测试:单元、验收、负载、可用性等。
    • 客户定期地参与对已完成部分的评估,从而使开发人员获得对调整和澄清需求的反馈。
    • 已经对系统(包括所有子系统)进行了完整的集成和固化,使其称为基线化的内部版本。

    迭代2很大程度上忽视了案例研究的需求分析和领域分析,而是着重于使用职责和GRASP进行对象设计,并且应用一些GoF设计模式。

    不应该把一个场景分开在多次迭代中处理,一次迭代应该完成一个或多个端到端的场景。


    Chapter. 24 快速地更新分析

    在对领域建模有了一些经验后,建模者就可以估计是否存在一组新的需求将会对领域模型在许多新概念、关联和属性方面产生或小或大的影响。此时要解决的需求并不会涉及许多新的领域概念。在这种情况下,应该跳过对领域模型的精化,快速投入到设计工作中。

    在本次迭代中没有考虑新的系统操作,故不需要契约。


    Chapter. 25 GRASP:更多具有职责的对象

    本章介绍了剩下的四个GRASP模式:多态、间接性、纯虚构、防止变异。


    Chapter. 26 应用GoF设计模式

    网上有篇文章总结得很好

    GoF设计模式分为三大类:创建性模式(5种)、结构性模式(7种)、行为性模式(11种)。

    GRASP是站在面向对象设计的角度,告诉我们怎样设计问题空间中的类与分配它们的行为职责,以及明确类之间的相互关系等,而不像GoF模式一样是针对特定问题而提出的解决方案。因此GRASP站在一个更高的角度来看待面向对象软件的设计,它是GoF设计模式的基础。

    创建型模式(5):

      1、原型模式:通过复制一个已存在对象来生成一个新对象,被复制的对象称为原型;详情...

      2、单例模式:一个类只有一个全局实例;详情...

      3、生成器模式:对复杂对象的创建过程进行抽象,相同的创建步骤,不一样的创建过程实现,生成不同表示的对象;详情...

      4、工厂方法模式:具体的工厂对象负责生产具体的产品对象;详情...

      5、抽象工厂模式:就是对一组具有相同主题的工厂进行封装;详情...

      简单工厂模式:一个工厂方法,依据传入的参数,生成对应的具体产品对象;//不属于gof-23 详情...

    结构型模式(7):

      1、装饰模式:通过关联机制给类增加行为,其行为的扩展由修饰对象来决定;详情...

      2、享元模式:大量细粒度对象共享复用;详情...

      3、桥接模式:将对象的行为抽象为接口,作为抽象类的成员属性在抽象层进行组合;详情...

      4、组合模式:树形结构的实现,用于描述“整体-部分”的关系;详情...

      5、外观模式:在子系统中的接口之上定义一个更高层次的接口,方便使用子系统中的接口;详情...

      6、代理模式:通过代理对象间接控制并访问目标对象的方法;详情...

      7、适配器模式:适配器是将一种接口改造成另外一种接口的一个包装类;详情...

    行为型模式(11):

      1、解释器模式:定义一些语法规则,然后定义一个解析器去解析该语法;详情...

      2、访问者模式:在不修改已有程序结构的前提下,通过添加额外的“访问者”来完成对已有代码功能的提升;详情...

      3、备忘录模式:保存对象的某个状态并可以恢复到该状态;详情...

      4、中介者模式:对象之间通过中介者对象进行交互,而不是直接交互;详情...

      5、模板方法模式:使用了JAVA的继承机制,在抽象类中定义一个模板方法,该方法引用了若干个抽象方法(由子类实现)或具体方法;详情...

      6、责任链模式:为请求创建一个接收者对象的链,每个接收者包含对另一个接收者的引用,当某个接受者不能处理该请求时,将请求转给下一个接受者;详情...

      7、命令模式:将请求封装成命令对象,请求的具体执行由命令接收者执行;详情...

      8、状态模式:一个对象的行为根据其内部状态的改变自动变化;详情...

      9、策略模式:对象的行为,在不同的环境下,有不同的实现;详情...

      10、迭代器模式:提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。详情...

      11、观察者模式:一对多的关系,又叫发布-订阅模式,即一个对象的状态发生变化,所有依赖它的对象能够知道该变化并自动更新;详情...

    重点考察以下三个模式:

    Single Ton 单实例模式
    问题:只希望有一个对象,系统所有地方都可以用到这个对象
    解决:确保单实例

    Observer 观察者模式
    问题:当一个对象改变时,所有依赖于它的对象要更新数据
    解决:定义对象之间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会自动获得通知

    Factory Design Pattern 工厂模式
    问题:跟防止变异很像
    解决:定义了一个创建产品对象的工厂接口,将实际创建工作推迟到子类中

    涉及的相关设计原则:

    • 单一职责原则
    • 里氏替换原则
    • 依赖倒置原则
    • 接口隔离原则
    • 迪米特法则
    • 开闭原则

    Chapter. 27 迭代3——中级主题

    迭代3涉及的主题比较宽泛,将探讨各种各样的分析和设计主题,包括:

    • 更多GoF设计模式及其内在框架的设计中的应用。
    • 架构分析;使用N+1视图模型对架构建立文档。
    • 使用UML活动图对过程进行建模。
    • 泛化和特化。
    • 包的设计。

    Chapter. 28 UML活动图及其建模

    UML活动图包括动作(action)、分区(partition)、分叉点(fork)、连接点(join)和对象节点(object node)等。有两点细微之处:一旦某个动作完成,紧接着会有一个自动的向外转换;活动图能够既表示控制流又表示数据流。

    数据流图(DFD)用于对软件系统过程中所涉及的主要步骤和数据进行可视化。DFD可以用来记录主要数据流或进行较高层面的数据流设计。

    除对象节点以外,UML数据存储节点(datastore node)也适用于表示数据流。

    统一过程的规程之一是业务建模(business modeling),其用途是去理解和沟通”将要部署系统的组织的结构和动态特征“。业务建模规程的关键制品是业务对象模型(UP中领域模型的超集)。


    Chapter. 29 UML状态机图和建模

    UML状态图是动态视图。

    UML状态机图(state machine diagram)描述了某个对象的状态和感兴趣的时间以及对象相应该事件的行为。状态图不必描述所有可能的事件,如果所发生的事件未在图中表示,则说明其不影响该状态机图所关注的内容。

    事件(event)是指意见值得注意的事情的发生;状态(state)是指对象在事件发生之间某时刻所处的情形;转换(transition)是两个状态之间的关系,它表明当某事件发生时,对象从先前的状态转换到后来的状态。

    如果一个对象对某事件的响应总相同,则认为此对象对于该事件状态无关(或非模态)。若对于所有事件,对象的相应总是相同的,则该对象是一个状态无关对象。相反,状态依赖对象对事件的相应根据对象的状态或模式而不同。

    转换可以出发动作。在软件实现中,这可能意味着状态机图所表示对象的某个方法的调用。

    一个状态允许嵌套,以包含自状态;自状态集成其父状态的所有转换。

    在UP中没有叫”状态模型“的东西。事实上,任何模型中的任何元素都可以使用状态机来帮助理解它们响应事件的动态行为。


    Chapter. 30 用例关联

    用例彼此之间可能具有联系。用例关系具有一些价值,但更重要的工作是编写用例文本。说明需求是通过编写用例文本完成的,而不是通过组织用例完成的,组织用例只是可选步骤,可能会改善对用例的理解、减少重复。

    用例关联包括:包含(include)和扩展(extend)两类。

    具体用例(concrte use case)是由参与者发起,完成了参与者所期望的完整行为。抽象用例(abstract use case)永远不能被自己实例化,它是其他用例的子功能用例。

    包含其他用例的用例,或者是被其他用例扩展或者泛化的用例称为基础用例(base use case)。被其他用例包含的用例,或者扩展、泛化其他用例的用例称为附加用例(addition use case)。

    扩展点的使用以及扩展用例是由某些条件所触发的。事实上,直接更新基础用例的扩展部分是推荐的方法,这样避免了创建复杂的用例关系。


    Chapter. 31 领域模型的精化

    泛化和特化是领域建模中支持简练表达的基本概念;更进一步将,概念类的层次结构经常成为激发软件类层次结构设计的灵感源泉。软件类层次结构设计利用继承机制减少了代码的重复。

    诸如概念分类列表(concept category list)、名词短语识别(noun phrase identification)这样的技术对开发领域模型会有所帮助。

    泛化(generalization)是在多个概念中识别共性和定义超类(普遍概念)与子类(具体概念)关系的活动。此活动对概念进行分类学意义上的分类,并将其在类层次结构中表示出来。

    概念超类(conceptual superclass)的定义较子类的定义更为概括或包含范围更广。概念子类集合的所有成员都是其超类集合的成员。

    Is-a规则:子类集合的所有成员必须是其超类集合的成员。使用自然语言,通常可以通过构造下面的陈述语句进行非正式的测试:子类是一种超类。

    概念类的划分(conceptual class partition)是指将一个概念类划分为几个不相交的子类。

    在下述几种情形下创建概念类的子类:

    • 子类有额外的有意义的属性
    • 子类有额外的有意义的关联
    • 子类概念的操作、处理、反应或使用的方式不同于其超类或其他子类,而这些方式是我们所关注的
    • 子类概念表示了一个活动体,其行为与超类或者其他子类不同

    如果类C的每个成员也必须是某个子类的成员,则类C被称为抽象概念类(abstract conceptual class)。

    继承(inheritance)是使超类的特性是英语子类的软件机制,它支持对子类代码的重构,将其置入超类之中,形成类层次结构。

    组合(composition)也称为组成聚合(composite aggregation),这是一种很强的整体-部分聚合关系,并且在某些模型中具有效用。

    在关联中可能会用到限定词(qualifier);基于限定词的值可以区分位于关联另一端的对象集合。具有限定词的关联是受限关联。

    概念到自身的关联称为自反关联(reflexive association)。

    将领域模型划分为包结构时,将满足下述条件的元素放在一起:

    • 在同一个主题领域,概念或目标密切相关的元素
    • 在同一个类层次结构中的关系
    • 参与同一个用例的元素
    • 有很强的关联性的元素

    Chapter. 32 更多的SSD和契约

    课本上继续介绍案例,无知识点


    Chapter. 33 架构分析

    架构分析可以被视为需求分析的规格化,其关注强烈影响“架构”的需求。架构分析的本质是要识别影响架构的因素,理解这些因素的可变性和优先级,并且解决这些问题。

    架构分析有助于:

    • 降低在系统设计中丢失某些重要因素的风险
    • 避免在低优先级的问题上花费过多的精力
    • 有助于产品与业务目标的一致

    变化点(variation point):当前现有系统或需求中的变化之处。

    进化点(evolution point):现有需求中不存在、但可能在将来发生,推测性的变化点。

    架构分析(architectural analysis)是在功能性需求的语境中,识别和处理系统非功能性需求的活动。

    在UP中,具有架构意义的因素被称为关键架构需求(architecturally significant requirement)。

    架构分析时,关注分离(separation of concern)是另外一个基本原则。横切面关注(cross-cutting concern)是指在系统中具有广泛应用或影响的事物。

    在UP中,架构性因素被记录在补充规格说明中,解决这些需求的架构性决策被记录在软件架构文档(SAD)中。


    Chapter. 34 逻辑架构的精化

    对三层架构的经典描述如下:

    • 接口
    • 应用逻辑
    • 存储

    Chapter. 35 包的设计

    包内部的耦合程度或关系内聚(relational cohesion),可以被定量地度量。


    Chapter. 36 使用GoF模式完成更多对象设计

    没什么好说的,就是讲案例


    Chapter. 37 使用模式设计持久性框架

    持久性框架(persistence framework)是一组通用的、可复用的、可扩展的类型,它提供支持持久性对象的功能。

    框架应该提供以下功能:从持久存储装置中存储和提取对象、提交或回滚事务。


    Chapter. 38 UML部署图和构件图

    部署图表示的是如何将具体软件制品分配到计算机诶单上,表示了软件与阿奴在物理架构上的部署,以及物理元素之间的通信。部署图中最基本的元素是节点(node)。节点之间的一般连接表示一种通信路径(communication path)。

    构件是一个较模糊的概念,因为类和构件都可用来对同一事物建模。构件(component)表示封装了其内容的系统模块,它在其环境中的表现形式可以被替代。


    Chapter. 39 架构的文档化:UML和N+1视图模型

    描述软件架构的文档称为“软件架构文档”(software architecture document, SAD)。

    了解即可。


    Chapter. 40 迭代式开发和敏捷项目管理的进一步讨论

    问题很多很杂:

    • 如何计划一次迭代
    • 适应性计划与预测性计划
    • 阶段计划和迭代计划
    • 如何使用用例和场景来计划迭代
    • 早期预算的有效性
    • 将项目制品组织起来
  • 相关阅读:
    C# 学习之旅(1)
    SqlServer安装教程
    Aop和Filter区别
    Redis入门
    SpringMVC与Struts2的主要区别
    SpringMVC执行流程
    ssm初始化环境搭建
    Oracle 高效分页
    Oracle 综合:游标和动态SQL
    Oracle 动态SQL
  • 原文地址:https://www.cnblogs.com/JHSeng/p/11105232.html
Copyright © 2020-2023  润新知