(个人复习用)软件建模与设计(待补充)

  • 复杂系统
  • 控制软件复杂性的基本方法
    • 分解(把大问题化解成小问题)
    • 抽象(抽取基本特性,忽略其他)
    • 模块化(高内聚、低耦合)
    • 信息隐蔽(封装,只需要知道模块功能而不需要了解内部细节)
  • 面向对象
    • 特性
    • 开发模式
  • UML
    • 视图分类(4+1)
  • 类模型(描述内部对象及其关系)
    • 对象(拥有唯一标识)
    • 类(拥有相同属性、行为、关系的一组对象)
    • 类图
        • 值和属性
          • 属性可见性
        • 操作&方法
        • 链接(对象之间的连接,关联的实例)
        • 关联(类之间的联系)
          • 自关联(与自身关联,但关联两端的角色不同)
          • 限定关联(带有限定符,降低多重性关联)
          • N元关联(无法用编程语言和建模工具表示,需要提升为类)
            • 聚合(强类型,由多个部件构成)
            • 组合(整体与部分有相同生存期)
        • 泛化(is-a-kind-of,父类与子类之间的关系)
        • 继承
          • 里氏代换原则(判断继承存在)
          • 多重继承(允许多个父类、尽量避免)
        • 枚举(有限取值的集合)
        • 抽象类
  • 状态模型(随时间发生变化)
    • 状态
    • 迁移(从一个状态到另一个状态的瞬时变化)
        • 组成部分
        • 描述格式
    • 事件
        • 外部事件(系统与其参与者之间传送的事件)
        • 内部事件(在系统内部对象之间传送的事件)
        • 调用事件(对操作调用,类似函数)
        • 信号事件(发送或接受信号的事件)
            • 信号(一个对象到另一个对象的单向信息流动)
            • 版型(用<<>>表示,是UML基础元素的扩展)
            • 信号类表示(类名上方加 < < << <<signal > > >> >>
            • 发送信号( < < << <<send > > >> >>
            • 信号建模原则(???)
        • 变化事件(满足布尔表达式)
        • 时间事件(满足时间相关布尔表达式)
        • 动作(不可被中断,执行时间忽略不计)
            • do动作(持续一段时间的一段活动,只在某个状态内出现)
            • 进入动作(进入某个状态时执行)
            • 退出动作(退出某个状态时执行)
    • 状态图(描述对象在其生存期间的动态行为)
        • 单触发状态图(有限生存期,有初始状态和终止状态)
    • 高级状态建模
        • 扩展状态(带有扩展了某些状态的子图(子状态机))
        • 嵌套状态
        • 组合状态(含有子状态的状态)
        • 子状态(嵌套在另一个状态中的状态)
            • or关系(某一时刻只能到达一个子状态)
            • and关系(并发关系,某一时刻可以到达多个子状态)
            • 聚合并发(即聚合基础上并发)
    • 有关用户界面的建模
  • 交互模型(对象协作完成任务)
    • 用例模型(捕获功能性需求)
        • 用例
            • 参与者(在系统之外,可以是人、硬件或系统)
        • 用例描述(用自然语言)
            • 描述用例容易犯的错误
            • 构建用例模型指南
        • 用例关系(不要过度使用,不要用到编程中)
            • 包含( < < << <<include > > >> >>,类似子程序)
            • 扩展( < < << <<extend > > >> >>
            • 泛化
    • 顺序模型(描述系统用户观测到的行为序列)
        • 场景(在某个特定的执行期内所发生的一系列事件)
        • 顺序图(按事件顺序排列,显示对象交互)
          • 对象命名方式
            • 顺序图的绘制
            • 结构化控制
        • 包含独立对象的顺序模型
        • 过程化顺序模型
        • 带有被动对象的顺序图
            • 被动对象
        • 建立顺序模型的准则
    • 活动模型(通过活动表述系统,可以表示控制流和数据流)
        • 活动图与交互图的区别
        • 活动图
            • 活动
            • 动作状态(原子性,占用时间忽略不计)
            • 活动状态(非原子性,需要占用一定时间)
            • 泳道(区域划分)
            • 分支、分叉(并发)、汇合(并发)
            • 对象流(输入输出)
        • 活动模型准则
  • 软件系统分析
    • 软件开发过程
        • 软件开发阶段
        • 开发生命周期
            • 瀑布式开发(需求较为明确的应用。高版本号的开发才可能出现)
            • 迭代开发(首选方式,风险小,灵活)
    • 系统构思
        • 软件项目的起源
            • 形成系统概念
            • 阐释概念(对新概念进行详细描述)
            • 准备问题陈述(描述系统目标、提出总体方案)
    • 分析
      • 领域分析
        • 领域类模型(描述真实世界的类及其关系)
          • 步骤
            • ※寻找类(物理实体,概念。不是所有名词都是类)
            • 准备数据字典(对建模元素的名字解释)
            • ※寻找关联(对应的动词或动词短语)
            • ※寻找对象和链接的属性(通常对应名词)
            • ※使用继承组织和简化类
            • 验证可能查询的访问路径
            • 迭代并细化模型(不会一次就得到正确的模型)
            • 重新考虑类的抽象层次
            • 把类组织成包
        • 领域状态分析
      • 应用分析
        • 应用的交互模型
          • 步骤
            • 确定系统边界(即应用程序的准确范围)
            • 寻找参与者(与系统交互的外部对象)
            • 寻找用例(系统提供的一类功能或服务)
            • 寻找初始和终止事件
            • 准备普通场景(没有任何异常输入或错误条件的交互)
            • 增加变化和异常场景(特例、错误情况、除基本交互外的其他交互形式)
            • 寻找外部事件
            • 编制复杂用例的活动图
            • 组织参与者和用例(用泛化、包含、扩展等)
            • 检查领域类模型
        • 应用的类模型
          • 步骤
            • 确定用户界面
            • 定义边界类(将传输信息在内部系统之间往来转换)
            • 确定控制器(管理应用程序控制权的主动对象)
            • 检查交互模型(考察用例的交互行为)
        • 应用的状态模型
            • 步骤
  • 软件系统设计
    • 系统分析(不关心怎么做,重点在于解决什么)
    • 系统设计(确定整体结构&风格,设计出解决问题的基本方法)
      • 估算系统性能(只需要大致估算,确定软件系统是否可行)
      • 指定复用计划
        • 分类
        • 可复用的事物(模型、类库、框架、模式)
      • 将系统划分为子系统
        • 子系统
          • 拆分子系统的方法
      • 确定问题内部的并发性(用状态模型识别)
      • 分配子系统(分配给硬件单元或功能部件)
      • 管理数据存储
      • 处理全局资源(确定资源访问控制)
        • 类型
      • 选择软件控制策略(外部&内部)
        • 外部控制流程(外部可见事件流)
        • 内部控制流程(进程内部控制流)
      • 处理边界条件(系统单初始化、系统运行的终止、运行过程中的失效)
      • 设置权衡优先级(开发代价、性能、效率之中寻找的平衡点)
      • 选择架构风格
        • 批处理转换
        • 连续型转换
        • 交互式界面
        • 动态仿真
        • 实时系统
        • 事务管理器
    • 类设计(完成类和关联的定义,设计操作的算法)
      • 填补鸿沟(高层需求和底层服务之间)
      • 用操作实现用例
      • 定义操作的算法
      • 向下递归,设计支持更高层的操作(用分层阻止操作)
        • 按功能递归分层
        • 按机制递归分层
      • 重构模型以实现更清晰的设计
      • 优化数据访问路径
      • 实现具体的行为(硬代码的操作代码在运行时可以动态修改)
      • 调整继承关系
      • 组织类和关联
    • 类的抽象层次
      • 组成
        • 概念层
        • 说明层
        • 实现层
      • 面向对象的基本设计原则
        • 开闭原则(最重要的)
        • Liskov替换原则
        • 依赖倒置原则(依赖抽象类/接口而不是具体类)
        • 接口分离原则
          • 接口污染(为借口添加了不必要的职责)
          • 分离接口的方法

复杂系统

具有层次形式
对于基本组件的选择在很大程度上依赖于系统观察者的判断
组件内部之间的联系比组件之间的联系更强
通常由几个不同种类的子系统通过各种排列组合而成
能够从简单系统演化而来

控制软件复杂性的基本方法

分解(把大问题化解成小问题)

通用策略(大问题化小)
面向对象策略(拆分为各个组成部分)

抽象(抽取基本特性,忽略其他)

类型抽象
服务激活抽象(函数调用、、时间处理、信息传递、订阅)
进程控制抽象(单程序执行、多任务、顺序执行、多线程)
关系抽象(关联、聚合)
行为(静态行为、动态行为)
规则(控制规则、业务规则、异常处理规则、竞争规则、触发器)

模块化(高内聚、低耦合)

信息隐蔽(封装,只需要知道模块功能而不需要了解内部细节)

面向对象

面向对象=对象+类+继承通信
适应性、可靠性

特性

标识、分类、继承、多态

开发模式

瀑布模型(不推荐)
迭代模式

UML

视图分类(4+1)

用例视图、逻辑视图、实现视图、进程视图、部署试图

类模型(描述内部对象及其关系)

对象(拥有唯一标识)

类(拥有相同属性、行为、关系的一组对象)

类是对“对象”的抽象

类图

命名(要唯一):英文首字母要大写、中文也可。

值和属性

(个人复习用)软件建模与设计(待补充)_第1张图片

属性可见性

public(+)
private(-)
protected(#)
package(~)

(个人复习用)软件建模与设计(待补充)_第2张图片

操作&方法

(个人复习用)软件建模与设计(待补充)_第3张图片

链接(对象之间的连接,关联的实例)

(个人复习用)软件建模与设计(待补充)_第4张图片

关联(类之间的联系)

(个人复习用)软件建模与设计(待补充)_第5张图片
关联可以是一对一、一对多、可能是多对多
具体描述:
1:1个
0…1:0个或1个
0…*:0个或多个

自关联(与自身关联,但关联两端的角色不同)

(个人复习用)软件建模与设计(待补充)_第6张图片

限定关联(带有限定符,降低多重性关联)

(个人复习用)软件建模与设计(待补充)_第7张图片

N元关联(无法用编程语言和建模工具表示,需要提升为类)
聚合(强类型,由多个部件构成)

具有传递性(A是B一部分,B是C一部分,则A是C一部分)
(个人复习用)软件建模与设计(待补充)_第8张图片

组合(整体与部分有相同生存期)

(个人复习用)软件建模与设计(待补充)_第9张图片
(个人复习用)软件建模与设计(待补充)_第10张图片

泛化(is-a-kind-of,父类与子类之间的关系)

子类的对象可以被用在父类的对象可能出现的任何地方,反之则不然
支持多态、可结构化描述、支持代码复用

继承

里氏代换原则(判断继承存在)

任何基类出现的地方都可以被其子类替换
如果父类所有行为都可以替换,那继承关系成立,反之则不能。

多重继承(允许多个父类、尽量避免)

java不允许多重继承,但可以通过接口实现类似功能

继承最重要的类、委派其他的类
只保留最重要的继承关系,把其余的继承关系变为组合关系
(个人复习用)软件建模与设计(待补充)_第11张图片
(个人复习用)软件建模与设计(待补充)_第12张图片

枚举(有限取值的集合)

属性的枚举即其多重性

抽象类

斜体字标识抽象类与抽象方法

状态模型(随时间发生变化)

包含多个状态图,每个类对应一个状态图

状态

所有对象都有状态
状态时对象执行了一系列活动的结果
某事件发生后,对象的状态将发生变化

迁移(从一个状态到另一个状态的瞬时变化)

迁移的源和目标可以是相同的,也可以是不同的。
可以通过事件触发,或是内部活动自动触发

组成部分

源状态
事件触发器
警戒条件迁移条件的布尔表达式,用**[]括起来)
效应(迁移激活时
执行的行为**)
目标状态

描述格式

事件特征标记[警戒条件]/动作
e g : t a r g e t A t ( p ) [ i s T h r e a t ] / t . a d d T a r g e t ( p ) eg:targetAt(p)[isThreat]/t.addTarget(p) eg:targetAt(p)[isThreat]/t.addTarget(p)

事件

外部事件(系统与其参与者之间传送的事件)

eg:操作者按下开关按钮

内部事件(在系统内部对象之间传送的事件)

eg:缓冲区溢出

调用事件(对操作调用,类似函数)

事件名(事件参数表,用逗号隔开)

信号事件(发送或接受信号的事件)

信号(一个对象到另一个对象的单向信息流动)

是对象之间的消息
由一个对象异步发送,并由另一个对象接收的已命名对象

版型(用<<>>表示,是UML基础元素的扩展)

用例版型:如“业务用例”,“业务用例实现”
类版型:如“信号类”,“接口”

信号类表示(类名上方加 < < << <<signal > > >> >>

(个人复习用)软件建模与设计(待补充)_第13张图片

发送信号( < < << <<send > > >> >>

(个人复习用)软件建模与设计(待补充)_第14张图片

信号建模原则(???)

考虑一组给定的主动对象可能响应的所有不同种类的信号。
寻找信号的公共种类,并使用继承将它们放在层次结构中。
在主动对象的状态机中寻找多态性,在发现多态性的地方,必要时通过引入中间的抽象信号来调整层次结构。
(个人复习用)软件建模与设计(待补充)_第15张图片

变化事件(满足布尔表达式)

不断检测表达式,只要为真,事件就会发生。
when(表达式)/动作

时间事件(满足时间相关布尔表达式)

when/at/after(表达式)/动作
其中,when和at是绝对时间事件,after是相对时间事件

动作(不可被中断,执行时间忽略不计)

do动作(持续一段时间的一段活动,只在某个状态内出现)
进入动作(进入某个状态时执行)

entry/动作

退出动作(退出某个状态时执行)

exit/动作

状态图(描述对象在其生存期间的动态行为)

(个人复习用)软件建模与设计(待补充)_第16张图片

单触发状态图(有限生存期,有初始状态和终止状态)

实心圆表示默认初始在这里插入图片描述
靶心圆表示默认终止在这里插入图片描述

高级状态建模

扩展状态(带有扩展了某些状态的子图(子状态机))

嵌套状态

组合状态(含有子状态的状态)

子状态(嵌套在另一个状态中的状态)

(个人复习用)软件建模与设计(待补充)_第17张图片
(个人复习用)软件建模与设计(待补充)_第18张图片

or关系(某一时刻只能到达一个子状态)

(个人复习用)软件建模与设计(待补充)_第19张图片

and关系(并发关系,某一时刻可以到达多个子状态)

(个人复习用)软件建模与设计(待补充)_第20张图片

聚合并发(即聚合基础上并发)

(个人复习用)软件建模与设计(待补充)_第21张图片

有关用户界面的建模

尽量避免使用UML对用户界面建模
用户界面建模应结合用户界面设计图或者用户界面的原型(控件、布局等)

交互模型(对象协作完成任务)

用例模型(捕获功能性需求)

(个人复习用)软件建模与设计(待补充)_第22张图片

用例

(个人复习用)软件建模与设计(待补充)_第23张图片
用例可以分为可选动作序列异常动作序列

参与者(在系统之外,可以是人、硬件或系统)

同一个用户可以在不同情况下扮演不同的参与者角色。

用例描述(用自然语言)

阅读对象为开发人员、用户、项目经理、测试人员等。
(个人复习用)软件建模与设计(待补充)_第24张图片
(个人复习用)软件建模与设计(待补充)_第25张图片
(个人复习用)软件建模与设计(待补充)_第26张图片

描述用例容易犯的错误

只描述系统的行为,而没有描述参与者行为
只描述参与者的行为,而没有描述系统的行为
在用例描述中就设定对于用户界面的设计要求。
描述过于冗长

构建用例模型指南

确定边界关系
确定关注参与者(每个参与者应该有单一、一致的目的)
每个用例必须给用户提供价值
关联用例与参与者
用例是非形式化
用例可以结构化

用例关系(不要过度使用,不要用到编程中)

包含( < < << <<include > > >> >>,类似子程序)

A(基本用例)->B(包含用例)表示A依赖于B
(个人复习用)软件建模与设计(待补充)_第27张图片

扩展( < < << <<extend > > >> >>

为用例添加增量行为
A(扩展用例)->B(基用例),表示A是B的扩展
(个人复习用)软件建模与设计(待补充)_第28张图片

泛化

使用父用例来表示通用行为序列
子用例特殊化父用例
(个人复习用)软件建模与设计(待补充)_第29张图片

顺序模型(描述系统用户观测到的行为序列)

场景(在某个特定的执行期内所发生的一系列事件)

顺序图(按事件顺序排列,显示对象交互)

对象命名方式

1.显示对象名与类名->“objectName:ClassName”
2.显示类名->“ClassName”
3.显示对象名->“objectName”

顺序图的绘制

把参与交互的对象或角色放在图的上方,沿水平轴方向排列。
发起交互的对象或角色放在左边,较下级对象或角色依次放在右边。
把对象发送和接收的消息沿垂直轴方向按时间顺序从上到下放置。
(个人复习用)软件建模与设计(待补充)_第30张图片

结构化控制

可选执行:opt
条件执行:alt
并行执行:par
循环(迭代)执行:loop

包含独立对象的顺序模型

所有对象都是并发活动的。
发送消息时,对象仍然保持活动状态,并可响应其他消息而不用等待响应。

过程化顺序模型

限制一次可执行的对象数量。

带有被动对象的顺序图

被动对象

被调用时才激活。
没有自己的控制线程。
执行完毕后控制权返回给调用者,被动对象重新变为不活动的。

(个人复习用)软件建模与设计(待补充)_第31张图片

建立顺序模型的准则

至少为每个用例编写一种场景。
把场景抽象为顺序图。
划分复杂的交互。
为每种错误条件绘制一张顺序图。

活动模型(通过活动表述系统,可以表示控制流和数据流)

活动图与交互图的区别

交互图强调对象与对象之间的控制流。
活动图强调步骤到步骤之间的控制流。

活动图

活动

表示算法语句或任务的执行。

动作状态(原子性,占用时间忽略不计)

执行进入动作,然后转向另一个状态

活动状态(非原子性,需要占用一定时间)
泳道(区域划分)

根据每个活动的职责对所有活动进行划分,每个泳道代表一个责任区。
一个泳道可能由一个或者多个类来实现。

分支、分叉(并发)、汇合(并发)

分支:根据不同警戒条件转向不用活动,每个可能的转移即分支。
分叉:一个控制流被两个或多个控制流代替。并发进行
汇合:两个或多个控制流被一个控制流代替。并发进行

对象流(输入输出)

一个对象值,从一个动作流向另一个动作。
表示活动与对象之间的关系。

活动模型准则

不要误用活动图
让图保持平衡
注意分支和条件
注意并发活动

软件系统分析

软件开发过程

软件开发阶段

系统构思:构思一项应用并系统地描述临时性需求。
分析:通过构造模型在更深入地理解需求。
系统设计:设计系统架构。
类设计:设计系统的真实模型及相关操作的算法。

实现:将设计转换成编码及数据库结构。
测试:确保应用满足实际需求。
培训:帮助用户掌握应用程序。
部署:安装应用软件,替代或连接已有系统。
维护:保证应用程序的长期有效性。

开发生命周期

瀑布式开发(需求较为明确的应用。高版本号的开发才可能出现)
迭代开发(首选方式,风险小,灵活)

系统构思

软件项目的起源

形成系统概念

针对某种需求形成的新的想法。
新概念可能偏离原有系统。

阐释概念(对新概念进行详细描述)

5W1H:who,what.where,when,why,how

准备问题陈述(描述系统目标、提出总体方案)

需求:从用户观点描述系统行为,系统被当作黑盒。
设计:选择适当的工程解决方案。
实现:将构思变成最终代码
描述要做什么,而不是怎么做!
问题描述本身可能是不完整、甚至错误的

分析

分析模型:类模型(静态结构)、交互模型(交互)、状态模型(生存期)
分析阶段:领域分析(分析问题的真实本质)、应用分析(从应用的角度来分析系统)
目标:深刻理解需求,设计准确、间接、可理解、正确的真实世界模型

领域分析

领域类模型(描述真实世界的类及其关系)

类模型优先级高于其他二者
1.静态结构容易定义
2.较少依赖应用程序的细节
3.解决方案演化时更稳定

步骤
※寻找类(物理实体,概念。不是所有名词都是类)

应该被剔除的类:
1.冗余类(留下描述最清楚的)
2.无关类
3.定义模糊的类(界限模糊或定义宽泛)
4.对象属性:(当某些对象的独立存在不重要时,可描述为属性,反之则为类)
5.对象的操作(方法)(若某个对象的操作独立存在时没有意义,则不应定义为类)
6.角色(类名称应反映其本质,而不是它在关联中的角色)
7.软件实现中用到的结构
8.派生类

准备数据字典(对建模元素的名字解释)

数据字典内容:
1.建模元素定义
2.类的作用域
3.受到的限制
4.关联、属性、操作、枚举

※寻找关联(对应的动词或动词短语)

描述成属性还是描述成关联?
当类中的属性需要指向类时,可使用关联。
关联显示的了类之间的关系。
属性隐藏了类之间的依赖。
编码实现时可有多种方式,实现时两者差别不大。
关联的原则
如果删除关联中的一个类,则应删除该关联。
删除问题领域之外或与系统实现有关的关联。
关联应描述为问题的结构特性,而非临时事件
将三元关联分解为二元关联。
忽略派生关联(前面加“/”的关联名)
给关联适当的命名
适当增加关联终端名
适当使用限定关联
指定关联端的多重性
增加可能被遗漏的关联
不必太严格区分聚合、组合、普通关联。

※寻找对象和链接的属性(通常对应名词)

寻找属性的原则
一个元素可以是属性也可以是独立类,视情况而定。
属性值依赖于特定上下文,应使用限定符
若名称依赖于上下文,则建模成限定符,反之则是属性。
不要把对象标识符建模成属性。
某些属性属于关联而不是类。
若某属性描述的是外部不可见的对象内部状态,则在分析阶段不应考虑。
在分析阶段忽略次要属性。
不要把无关属性整合在一起。
布尔属性扩展为枚举。

※使用继承组织和简化类

1.将现有类的公共部分泛化为类(自下而上)
2.将现有类特化为多个子类(自下而上)

原则:
1.慎用泛化
2.某些时候枚举比泛化更合适
3.慎用多重继承
4.可以考虑泛化关联类
5.适当的泛化层次

验证可能查询的访问路径

目的:跟踪类模型中的访问路径,确认是否产生符合实际的效果。
避免遗漏或错误地定义关联。

迭代并细化模型(不会一次就得到正确的模型)

类中有无关属性和操作->拆分类
有相同名称或意图的重复关联->泛化出父类,组合重复的关联
一个描述类的语义的角色->设计成独立的类
遗漏了关联->增加新的关联
不必要的模型元素(缺少属性、操作、关联。有冗余信息)
关联终端名范围不适当
属性值之一需要访问对象

重新考虑类的抽象层次

重新审视分析得到的类与关联

把类组织成包

尽量把关联限制在单个包之中
可以在不同的包中重复一些内类
高内聚低耦合

领域状态分析

1.确定具有状态的领域类
2.寻找状态
3.寻找事件
4.构造状态图
5.评价状态图

应用分析

应用的交互模型

步骤
确定系统边界(即应用程序的准确范围)

把系统看成黑盒(可与外界交互,内部细节隐藏 )
通常不把人看成系统

寻找参与者(与系统交互的外部对象)

参与者可以人、外部设备、其他软件系统
参与者的行为不可预测,因此系统应足够健壮以应对参与者的各种行为

寻找用例(系统提供的一类功能或服务)

在描述的详尽程度上,各用例应保持一致

寻找初始和终止事件

寻找用例事件开始,确定发起用例的参与者
寻找用例终止,确定用例应包含多少终止事件

准备普通场景(没有任何异常输入或错误条件的交互)
增加变化和异常场景(特例、错误情况、除基本交互外的其他交互形式)
寻找外部事件

外部事件:系统与用户或外部设备之间的交互导致的事件
输入、中断、决策等

编制复杂用例的活动图

顺序图描述主要流程,若有多个交互进程,用活动图合并

组织参与者和用例(用泛化、包含、扩展等)
检查领域类模型

应用的类模型

步骤
确定用户界面

用户界面不是分析阶段的重点,且不应过分关注细节。
尽量确定用户可以执行的命令。

定义边界类(将传输信息在内部系统之间往来转换)

方便系统操作与接收来自外部资源的信息
将系统内部与外部隔离开
提供系统与外部资源通信的一个集结地

确定控制器(管理应用程序控制权的主动对象)

作用:接收外界或系统内部信号,响应信号并调用心痛对象上的响应操作,并给外界发送信号。
特点:以对象的形式来捕获数据和行为;多数应用的核心都是一项或多项控制器。

检查交互模型(考察用例的交互行为)

应用的状态模型

步骤

用多个状态来确定应用类
使用交互模型来寻找类的事件
用状态图为每个类组织许可的事件序列。
检查状态图,确保公共事件的匹配。
用类和交互模型检查状态图,确保一致。

软件系统设计

系统分析(不关心怎么做,重点在于解决什么)

系统设计(确定整体结构&风格,设计出解决问题的基本方法)

估算系统性能(只需要大致估算,确定软件系统是否可行)

指定复用计划

分类

现有事物的复用
创建可复用的新事物进行复用(需要大量经验)

可复用的事物(模型、类库、框架、模式)

将系统划分为子系统

子系统

一组相关的类、关联、操作、事件和约束。
与其他子系统之间存在定义良好的小型接口
通过它提供的服务(相关功能)来识别

拆分子系统的方法

水平拆分:分层
闭合结构(减少耦合度):每一层只在其直接上下层之上构建。
开放架构(高效,高耦合度):某一层可以调用任一下层的功能。

垂直拆分:分区
分区和分层结合

确定问题内部的并发性(用状态模型识别)

必须是并发活动的对象
具有互斥活动的对象???

若两个对象在不交互的情况下可以在同一时间接收事件,则并发。

分配子系统(分配给硬件单元或功能部件)

估算硬件资源需求
权衡硬件和软件
给处理器分配任务
确定物理连通性

管理数据存储

文件形式:廉价、简单、持久
数据库形式:RDBMS,OODBMS

处理全局资源(确定资源访问控制)

类型

物理部件
空间
逻辑名称
对共享数据的访问

选择软件控制策略(外部&内部)

外部控制流程(外部可见事件流)

过程驱动型顺序控制流
时间驱动型顺序控制流(首选)
并发控制

内部控制流程(进程内部控制流)

过程调用
任务间的准并发调用
任务间的并发调用

处理边界条件(系统单初始化、系统运行的终止、运行过程中的失效)

设置权衡优先级(开发代价、性能、效率之中寻找的平衡点)

选择架构风格

批处理转换

接收输入信息,执行顺序计算,给出计算答案。
1.将整段拆分成不同阶段
2.为输入输出及每一对连续阶段,准备类模型
3.细化每个阶段,直到可以实现所有操作
4.重新构造最终的管道流程,以便优化

连续型转换

输出不断更新,依赖于不断发生变化的输入
1.将整个过程分为不同阶段,每个阶段完成一部分转换
2.为每一个连续阶段定义输入、输出与中间模型
3.区分不同的操作,以便获得每一阶段的增量变化
4.增加其他中间对象以便优化。

交互式界面

由系统和外部代理(人或设备)只配的系统
主要考虑系统和外部代理之间的通信协议、交互语法、输出表示、内部控制流、性能和错误处理
1.将界面类和应用类分离
2.尽量使用预定义的类与外部代理交互
3.以状态模型作为程序结构
4.分离物理事件和逻辑事件
5.明确所有界面调用的应用功能

动态仿真

对真实世界的对象进行建模与跟踪。
1.从类模型中确定主动的真实世界对象
2.确定离散事件,离散事件对应于对象的离散交互
3.确定连续的依赖性

实时系统

对执行动作有着非常严格的时间约束的交互式系统

事务管理器

存储和检索数据的系统
1.将类模型映射成数据库结构
2.确定并发单元(不能共享的资源)
3.确定事务单元(必须一起访问的资源集合)
4.设计事务的并发控制

类设计(完成类和关联的定义,设计操作的算法)

将分析阶段得到的类代入设计阶段,在类设计阶段对其进行细化

填补鸿沟(高层需求和底层服务之间)

设计的本质:弥补实现功能与可用资源之间的差距
可通过构建中间元素来弥补差距
(个人复习用)软件建模与设计(待补充)_第32张图片

用操作实现用例

设计出能实现用例分析中的功能和操作对象
设计对象应该实现的操作

定义操作的算法

1.选择成本最低的算法
2.选择合适的数据结构
3.按需定义内部类和操作
4.把操作分配给合适的类

向下递归,设计支持更高层的操作(用分层阻止操作)

按功能递归分层

准确定义高层功能,设计时将其分解为小的、易实现的操作
缺点:高层功能描述的偏差将导致分解后的操作偏离实际需要

按机制递归分层

对系统的支持机制进行分层,从而构造系统

重构模型以实现更清晰的设计

优化数据访问路径

实现具体的行为(硬代码的操作代码在运行时可以动态修改)

调整继承关系

1.重新调成类和操作以增加继承性
2.从分组类中提取公共行为
3.当继承在语义上不合理时,使用委派来共享行为

组织类和关联

隐藏内部信息使其不被外部视图所见
维护实体一致性

类的抽象层次

组成

概念层

说明层

实现层

面向对象的基本设计原则

开闭原则(最重要的)

一个模块在扩展性方面应该是开放的,在更改性方面应该是封闭的
1.使用接口进行封装
2.采用抽象机制
3.使用多态技术

Liskov替换原则

子类必须能够替换掉它们的父类型,否则继承关系就是不正确的

依赖倒置原则(依赖抽象类/接口而不是具体类)

接口分离原则

类与类之间的依赖应该表现为依赖尽可能小的接口。

接口污染(为借口添加了不必要的职责)

会带来严重的维护和重用方面的问题,被迫实现并维护不必要的方法

分离接口的方法

1.委托
2.多继承

你可能感兴趣的:(其他)