💡
  • 详细设计的出发点
  • 给定分析类图、系统顺序图和设计因素描述
    • 建⽴设计类图
      • 职责分配
    • 或者详细顺序图
      • 协作
      • 控制⻛格
  • 协作的测试
    • MockObject

详细设计的出发点

详细设计的出发点: 需求开发的结果(需求规格说明和需求分析模型)和软件体系结构的结果(软件体系结构设计⽅案与原型)
功能性和非功能性需求 + 框架性体系结构 → 进一步设计细化
一个提供方向, 一个提供框架
目的: 实现所有的(满足各处细节的)功能性和非功能性需求
结果(产物): 能够指导程序员编程的详细设计文档和详细设计原型代码.
明确职责建立静态模型(设计类图), 明确协作建立动态模型(详细顺序图)
💡
GRASP(General Responsibility Assignment Software Patterns) 是一组用于指导面向对象设计中职责分配的原则或模式, 由 Craig Larman 提出.
GRASP 不是设计模式(如 GoF 模式), 而是一套思想性的指导原则, 帮助我们决定哪个类该承担哪些职责, 从而实现高内聚、低耦合的设计.

GRASP 的 9 个核心原则
编号
原则名称(英文)
中文名称
作用说明
1
Information Expert
信息专家
将职责赋给拥有必要信息的类.
2
Creator
创建者
将对象的创建职责交给包含、聚合或使用该对象的类.
3
Controller
控制器
为系统事件分配一个负责接收并协调任务的类, 通常是“用例控制器”.
4
Low Coupling
低耦合
减少类之间的依赖, 提升模块独立性与可维护性.
5
High Cohesion
高内聚
一个类的职责应聚焦相关任务, 避免混杂不相关功能.
6
Polymorphism
多态
利用多态来替代条件判断, 实现灵活可扩展的行为变更.
7
Pure Fabrication
纯粹构造
引入人为类来实现低耦合或高内聚(如 DAO、Service).
8
Indirection
间接层
使用中间对象(如中介、适配器)解耦依赖双方.
9
Protected Variations
保护性变异
使用接口、抽象类或包装机制保护系统免受变化影响.

简要解释与示例
1. Information Expert(信息专家)
定义: 将职责赋给最具相关信息的类.
例子: 订单总价的计算应该由订单类来完成, 因为它知道包含哪些订单项.

2. Creator(创建者)
定义: 让包含或聚合另一个类的类来负责创建它.
例子: 订单类包含订单项, 因此可以负责创建订单项对象.

3. Controller(控制器)
定义: 为系统事件创建中介者类(通常是用例控制器).
例子: UI 层点击“下订单”时, 调用 OrderController 处理业务逻辑.

4. Low Coupling(低耦合)
定义: 降低类之间的依赖程度.
目的: 更容易修改、测试、重用.

5. High Cohesion(高内聚)
定义: 让类的功能职责集中, 不杂乱.
目的: 提升代码可理解性、可维护性.

6. Polymorphism(多态)
定义: 将可变行为封装进可替换的子类中, 使用多态替代条件判断.
例子: 用 Shape.draw() 调用圆形或矩形的具体绘制方法, 而非 if shapeType == ....

7. Pure Fabrication(纯粹构造)
定义: 为了高内聚低耦合而人为制造的类, 不直接反映现实世界实体.
例子: DAO 类是数据库操作的纯粹构造, 业务对象不直接处理 SQL.

8. Indirection(间接层)
定义: 通过引入中介类/接口来解耦.
例子: 使用接口或中间层处理两个对象之间的交互, 如事件监听器.

9. Protected Variations(保护性变异)
定义: 用稳定的接口或抽象层来封装变化点.
例子: 通过接口 PaymentProcessor 抽象支付实现, 避免业务层直接依赖某一支付平台.

总结: GRASP 的意义
GRASP 是指导我们合理划分类的职责、构建可维护、可扩展的系统架构的重要原则.
它不是一套固定套路, 而是一种设计思维, 强调:
  • 责任应该“落到谁身上”
  • 如何在不同对象之间分配逻辑
  • 如何保护系统在变更时的鲁棒性
掌握 GRASP, 有助于写出清晰、健壮、可演进的面向对象系统.

面向对象设计

将世界抽象成一系列具有一定职责的自由数据个体, 这些个体除了有自己独特的数据信息之外, 还包含了一些依赖这些数据信息能够做的事情. 个体只行使自己的职责, 遇到自己无法完成的事就相互发送消息要求其他个体帮助完成.
⾯向对象分解中, 系统是由很多对象组成的. 对象各⾃完成相应的职责, 从⽽协作完成⼀个⼤的职责.
将系统分解为这些小的自由数据个体时, 按照个体的单一职责进行分解.

设计类图

💡
通过职责建立静态模型
有类名, 属性, 方法, 类型
建立过程:
  1. 抽象对象的职责
      • 将对象抽象为类
      • 类的职责主要可分为属性职责(对象的状态)和方法职责(对象的行为)
      单一类图示例
      单一类图示例
      💡
      记得属性前标-号, 方法前标+号!
      参数的类型也标在参数名后面!
  1. 抽象类之间的关系
      • 类和类之间存在多种关系, 关系表达了相应职责的划分和组合
      • 强弱顺序为依赖 < 关联 < 聚合 < 组合 < 继承
      notion image
      关系图例
      关系图例
  1. 添加辅助类
      • 概念类(候选类)往往不能实现全部的功能, 需要添加一些辅助类
      • 辅助类: 接口类、记录类(数据类)、 启动类、控制器类、实现数据类型的类、容器类
设计模型示例
设计模型示例

详细顺序图

💡
通过协作建立动态模型
类和类, 对象和对象之间如何交互, 消息传递, 方法调用
抽象对象之间协作, 明确对象的创建, 选择合适的控制风格
可能给需求按某种控制方式画图
  1. 抽象对象之间的协作
      • 从小到大, 将对象的小职责聚合形成大职责
      • 从大到小, 将大职责分配给各个小对象
      • 通过这两种方法共同完成对协作的抽象
      • 对象之间的协作可以使用顺序图表示, 表达对象之间如何通过消息传递来完成比较大的职责. 顺序图分为对象本身(需标明生存周期)和对象之间的消息流(需表示何时哪个对象向另一个对象发送了什么消息)
        • notion image
  1. 明确对象的创建
      • 决定一个对象应该由哪个对象, 在什么地点/时机创建
      notion image
  1. 选择合适的控制风格
      • 为了完成某⼀个⼤的职责, 需要对职责的分配做很多决策. 控制风格决定了决策由谁来做和怎么做决策, 如何在负责控制和协调的对象之间分配各自的控制责任.
      • 集中式: 一个中心控制对象决定怎么分配职责, 怎么实现大的职责, 其他所有对象都只和该对象交互
      • 委托式: 做出决策的对象不止一个, 分别承担一定职责, 做出一定决策, 共同实现大的职责. 职责的分解层次决定了控制对象的层次. 控制对象还可以分解其职责到更低层次的控制对象, 委托其完成相应的任务
      • 分散式: 没有明确控制对象, 每个对象都只承担一个相对较小的职责, 完全靠各个对象自治的方式实现大的职责
      notion image
      notion image
      notion image
顺序图示例
顺序图示例

为类间协作开发集成测试用例

每个类被独立开发, 可能产生集成问题, 需要进行集成测试, 即类间协作的集成测试. 所以在详细设计之后, 需要以详细设计模型为基础, 为类间协作开发集成测试用例.
类间协作的集成可以使用自顶向下/自底向上两种方式.
  • 自顶向下: 从协作的发起端开始, 向协作的终端集成, 需要较少驱动代码和较多桩程序
  • 自底向上: 从协作的终端开始, 向协作的发起端集成, 需要较多驱动代码和较少桩程序
类间协作的桩程序常被称为Mock Object, 不同于体系结构集成中的stub, 要求自身的测试代码更简单, 不用测试就能保证正确性(如写死假数据直接返回).
Loading...