🥰名片:
🐳作者简介:乐于分享知识的大二在校生
🌳本系列专栏: (点击直达)统一建模语言UML
🫣致读者:欢迎评论与私信,对于博客内容的疑问都会尽量回复哒!!!
本文序:
⛰️本文介绍:本文是整个统一建模语言UML专栏的总起,由于之后的文章都是对于本文内容的更详细介绍,所以之后本专栏的文章都会在本文的相应地方附上跳转链接(注:因编者时间有限,所以有一些图片来源于网络,为了尊重原作者,所以选择保留水印)
⚓本文食用方法:本专栏可用于从0学习,考试,临时抱佛脚等等
❤️🔥如果本文对您有所帮助的话,请三连鸭UWU
一:介绍
1.1 定义
UML 指的是统一建模语言(Unified Modeling Language)。它是一种用于软件开发的标准图形化建模语言,用于描述软件系统的结构和行为。 UML提供了一系列的图形符号和建模概念,帮助开发人员更好地理解、设计和沟通关于软件系统的各种方面。
(UML是一个庞大的图形化表示法体系)
1.2 应用UML的三种方式
草图 :在项目开始之前,为开发人员、设计师和客户等,提供沟通的统一语言
蓝图 :在项目完成之后,为整个项目做一个描述,便于维护人员等,理解该软件系统
编程语言:这里的编程语言并不是指C++之类的,它的应用场景包括如下
正向工程 :从 UML 模型生成代码(如类图 → Java 类)。
例子:用 UML 工具设计一个订单类(包含属性、方法),工具自动生成对应的 Java 类代码框架。
逆向工程 :从代码反向生成 UML 模型(如 Java 类 → 类图)。例子:通过 IDE 插件将已有代码转换为 UML 类图,辅助理解系统结构。
可执行 UML :直接运行 UML 模型(如状态图驱动系统行为)。例子:用 UML 状态图定义"电梯运行逻辑",工具模拟电梯行为并生成可执行程序。
1.3 UML的要素
表示法 - 图形
过程 - (UML与过程无关,但最好用RUP)
工具 - 如Ratinal Rose
1.4 UML包括
UML包括: 事物 关系 图 扩展机制
事物 :
结构:类、接口、构件、节点等等
行为:交互(消息)、状态等等
分组:包、子系统等等
注释:注释
关系
泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregation),组合(Composition),依赖(Dependency)
各种关系的强弱顺序
: 泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
(聚合的例子:删掉某一个功能,其下游功能应该全部失效)
图
静态建模:类图
动态建模:顺序图(协作图),用例图,活动图,状态图
扩展机制:Stereotype(构造型)、Tagged Value(标记值)、Constraint(约束)
1.5 例子
◇ 骰子游戏:软件模拟游戏者投掷两个骰子,如果总点数是7则赢得游戏,否则为输
◇ 过程:定义用例--->定义领域模型--->定义交互图--->定义设计类图
◇定义用例(用例是需求分析的一种工具,它是一些情节的描述)
骰子游戏:
1、游戏者请求骰子2
2、系统展示结果:如果骰子的总点数是7,则游戏者赢;否则游戏者输回
◇ 定义领域模型(OOA)---识别问题中的概念,它是对真实世界领域中的概念和想像可视化,与具体实现的软件技术无关(比如java或C#):游戏者 骰子 骰子游戏



UML的图形表示法的简单例子


二:事物&&关系&&图&&扩展机制
2.1 事物
事物(Things)
- 结构事物
- 类 :
学生
类,包含属性(学号、姓名)和方法(选课、查询成绩)。- 接口 :
支付接口
,定义支付()
方法,具体实现由支付宝或微信支付类完成。- 构件 :一个可复用的
登录模块
,封装用户身份验证功能。
- 行为事物
- 交互 :用户点击登录按钮时,系统发送
验证请求
消息给服务器。- 状态 :订单从
待付款
→已发货
→已完成
的状态变化。
- 分组事物
- 包 :将电商系统的所有支付相关类(支付宝、微信、银联)放入
支付包
中管理。
- 注释事物
- 注释:在类图旁标注"此模块需在2023年底前完成重构"。
2.2 关系
关系(Relationships)
- 依赖(Dependency)
- 一种临时关系,比如变量传递等
- 例子 :
学生选课
方法需要传入课程
对象参数。若课程类结构改变,选课方法可能受影响。
- 关联(Association)
- 关联 :
学生
和课程
之间是"选课"关系,学生可选多门课程。(关联是类的实例之间的关系)- 聚合 (Aggregation):
汽车
(整体)由轮胎
(部分)组成,但轮胎可独立存在(换到另一辆车)。- 组合 (Composition):
订单
(整体)包含多个订单项
(部分),删除订单时订单项一并删除。 即,部分不能独立整体而存在
- 泛化(Generalization)
- 例子 :
猫
和狗
继承自动物类,复用eat()
和sleep()
方法。
- 实现(Realization)
- 例子 :
MySQL数据库类
实现数据库接口
中定义的connect()
方法。
- 操作契约是对系统行为进行更加详细和精确的描述,操作契约有操作,交叉引用,前置条件与后置条件
2.3图
图(Diagrams)
- 用例图:描述用户与系统的交互。
- 参与者:
顾客
,用例:下单
、支付
、查看物流
。
- 类图:展示系统静态结构。
学生
类关联课程
类,依赖成绩单
类。
- 顺序图:显示对象间消息传递顺序。
- 用户点击登录 → 界面层调用
验证服务
→ 服务返回结果。
- 活动图:描述业务流程。
- 购物流程:浏览商品 → 加入购物车 → 结算 → 支付 → 生成订单。
- 状态图:对象状态变化。
- 订单状态:
待付款
→已支付
→已发货
→已完成
。
2.4 扩展机制
扩展机制
- 构造型(Stereotype)
定义元素的角色或类别
例如用
<<Controller>>
标记用户管理控制器
类,表示它在MVC模式中的角色。格式如下:直接在类名上方用<<Stereotype>>标注
<<Entity>>
User
- id: String
- name: String
- save(): void
- 标记值(Tagged Value)
为元素添加自定义属性(如版本号、作者)
- 例如为类添加
版本号
标记,如{version=2.1}
。
- 约束(Constraint)
定义元素的规则或限制
- 例如在属性旁标注
{年龄 >= 18}
,限制用户注册时的年龄条件。
常见构造型示例
构造型 | 用途 | 示例 |
---|---|---|
<<Entity>> |
表示持久化数据或业务实体 | User , Order |
<<Boundary>> |
处理系统与外部的交互(如UI、API,如打印机API) | LoginForm , APIClient |
<<Control>> |
封装业务逻辑或流程控制 | OrderManager , AuthController |
<<Service>> |
提供通用服务(如日志、事务管理) | Logger , PaymentService |
<<Interface>> |
标记接口(与UML标准接口不同,标准接口写的就是interface,而这里的可以自定义,比如写REST表表示该接口是REST风格的API) | <<Repository>> ,<<gRPC>> ,<<REST>> |
<<template>> |
模板类 |
三:十三类图
3.1 类图
类图(Class diagram)以反映类的结构(属性、方法或操作),以及类之间的关系为主要目的,描述了软件系统的结构,是一种静态建模方法。
(uml使用类图表示类,接口及其关联,用于静态对象建模)
3.1.1 类的基本表示法
- 类的名字(Name):骰子
- 类的属性(Attribute,Property):点数
- 类的操作(方法)(Method,Operation):获取点数
(注:对于参数如何标注private或者public等等:把下面的-,+号等标注在参数旁边)

3.1.2 接口的基本表示法
-
圆形表示法
[类] ---------⚪<接口>
-
构造型表示法
接口用一个类矩形框表示,顶部标注构造型标记<<interface>>
<<interface>>
+接口名称+方法1()
+方法2()实现关系用虚线空心箭头(从类指向接口)或实线(带三角箭头)表示
[实现类] ------------▷ <<interface>> 接口名称
3.1.3 包
作用 :可以用来表示层次结构(子系统);可以用来组织各种内容
(图中为呈现层,业务逻辑层等)
(呈现层:通过多种图表(如用例图、类图、序列图)共同描述系统的用户界面和交互逻辑)
3.1.4 类之间的关系
(注:以下对于"关系"的解释,也适用于其他图)
依赖(一个事物的变化影响另外一个事物)
关联(关联名、导航、角色、多重性、聚合、组合)
泛化(extends):就是继承
实现(implements)

3.1.4.1 依赖关系
该组件需要用到什么,你就是依赖什么,下图为代码和图
如图,User Action依赖于UserManager,那么UserAction所在的模块《呈现层》和UserManager所在的《业务逻辑层》也是有相应的依赖关系
注 :
依赖的作用 :拥有提供者类型的属性,向提供者发送信息,接收提供者类型的参数,提供者是超类或接口
依赖标签 有call和create:
call含义:表示一个模块、函数或组件在运行时会调用另一个模块或函数,依赖于对方提供的服务或功能。
create含义:表示一个模块、函数或组件在运行时创建另一个模块或对象,它依赖于这个创建过程
依赖关系的核心特点
临时性:Driver 只在 drive 方法中临时使用 Car,并不长期持有它(没有将 Car 作为属性)。
代码体现:依赖通常出现在方法的参数、局部变量或返回值中(如 drive(Car car))。
UML 表示:虚线箭头从依赖类(Driver)指向被依赖类(Car)。
注 :低耦合:表示要降低跟不稳定的其他对象之间的依赖关系(而稳定的,比如相应API等等,并不是要低耦合的目标,是没必要也是不可能的) 补充:IOC与DI
3.1.4.2 关联关系
-
关联名
-
导航性
一般是实体间的联系
在代码中:表示引用关系
导航:如student.name(单向,双向)
CTRL+d:删除箭头

上图中user的角色名creator已经用关联表示,所以左上图的document没有creator字段

creator前面的符号:+为public,-为private,#为protect
- 多重性

学生和class之间是多个学生"关联于"一个class,对应*号和1符号

一个message对应于2个user,但是我们一般不这么画
注:若有关联则不需要依赖
3.1.4.3聚合与组合

聚合:飞机场是整体,飞机是部分(aggregate),飞机可以脱离飞机场独立存在
组合:是一种聚合,一个窗口包含按钮和菜单,按钮不可脱离窗口独立存在
3.1.4.4 实现关系
一般通过接口interface实现
3.1.4.5 操作契约
定义 :操作契约(Operation Contract)定义了在某个操作执行时,输入条件、预期行为以及输出结果的规范。操作契约通常用于精确定义类的操作如何执行,并且描述它的前置条件、后置条件以及操作本身的行为。
要素 :
前置条件(Preconditions)
:描述操作开始之前必须满足的条件。它规定了操作在执行前的系统状态或输入条件。
后置条件(Postconditions)
:描述操作执行完后,系统应该达到的状态或输出结果。它规定了操作执行后的效果。
交叉引用
:在描述操作时,引用与之相关的其他部分(如其他操作契约、类的状态、业务规则等),它有助于确保操作契约与系统其他部分的一致性
不变式(Invariants)
:描述在操作执行过程中始终保持的条件,不会因为操作执行而改变的系统状态。
操作本身的行为(Behavior)
:描述该操作的具体行为,可能会涉及多个步骤、条件判断、消息发送等。
例子:
操作名称:用户登录(Login)
前置条件:
1. 用户已经注册,并拥有有效的用户名和密码。
2. 用户的账户没有被禁用。
3. 系统处于正常运行状态,能够进行身份验证。(见系统状态,第2节)
后置条件:
1. 用户成功登录后,系统创建一个用户会话,并分配一个唯一的会话ID。
2. 用户能够访问自己的个人主页。
操作本身的行为:
1. 用户输入用户名和密码,点击"登录"按钮。
2. 系统验证用户名和密码。
3. 如果验证通过,系统创建一个用户会话,并分配会话ID;否则,返回错误消息。
4. 用户被重定向到个人主页。
不变式:
1. 用户的账户信息(用户名和密码)在系统中保持一致性。
2. 系统每次验证时都使用加密算法处理密码。
其中,"(见系统状态,第2节)"即交叉引用
3.1.5 补充
3.1.5.1 分析类图
类图是一个宽泛的概念,根据开发阶段的不同,可以细分为:
- 分析类图(需求分析阶段)
- 设计类图(系统设计阶段)
- 实现类图(编码阶段)
分析类图:是类图的一种具体应用形式,聚焦于需求分析阶段,用于描述系统需要处理的核心业务概念及其关系,不涉及技术实现细节。它本质上是类图的早期简化版本,属于类图的子集。

其中,UserAction为边界类,User为实体类(稳定),UserManager为控制类(活跃)
分析类图与类图(一般指设计类图)核心区别
维度 | 分析类图 | 类图(一般指设计类图) |
---|---|---|
目的 | 捕获业务需求中的核心实体和关系,明确"系统需要什么" | 描述系统具体实现结构,明确"系统如何构建" |
抽象层级 | 高抽象,仅关注业务概念,与技术无关 | 低抽象,包含技术细节(如方法、接口实现) |
内容元素 | - 类名、核心属性(无类型) - 简单关系(关联、聚合) | - 类名、完整属性(含数据类型) - 方法签名、接口实现 - 复杂关系(组合、依赖等) |
使用阶段 | 需求分析阶段(早期) | 系统设计阶段(中后期) |
示例 | 订单 类可能仅包含订单号 、金额 等属性,不定义具体方法 |
订单 类会定义calculateTotal() 方法,并关联到具体数据库操作类 |
需求分析阶段:
plaintext
[用户] -- 1..* [订单]
[订单] -- 1..* [商品]
设计阶段:
plaintext
class 用户 {
- userId: string
- name: string
+ createOrder(): Order
}
class 订单 {
- orderId: string
- total: double
+ calculateTotal(): void
}
3.1.5.2 控制类&边界类&实体类
控制类(Control Class)、边界类(Boundary Class)和实体类(Entity Class) 是三种常见的类分类方式,主要用于描述系统的不同职责和交互层次。
1. 基本概念与职责
类类型 | 定义 | 核心职责 | 特点 | 示例 |
---|---|---|---|---|
实体类 | 代表系统中持久化的业务实体,与数据库或数据存储直接关联。 | - 存储和管理业务数据 - 封装业务实体的属性和基本行为 -关注数据(业务实体的属性和持久化) | - 对应现实世界的对象(如用户、订单) - 通常与数据库表结构映射 - 独立于用户交互和技术实现 | User (用户)、Order (订单)、Product (商品) |
边界类 | 描述系统与外部参与者(用户、其他系统)的交互接口。 | - 处理输入/输出(如用户界面、API接口) - 转换外部请求为内部可处理的数据格式 -关注交互(系统与外部的输入/输出) | - 关注交互细节 - 与用户或外部系统直接接触 - 通常不包含业务逻辑 | LoginPage (登录页面)、OrderAPI (订单接口)、FileUploader (文件上传组件) |
控制类 | 协调多个类之间的操作,封装复杂的业务逻辑或流程控制。 | - 实现用例的流程逻辑(如订单创建流程) - 协调实体类和边界类的协作 - 处理事务和异常管理 -关注逻辑(业务流程和规则) | - 聚焦业务流程 - 通常无状态(不保存数据) - 与技术实现解耦 | OrderController (订单控制器)、PaymentProcessor (支付处理器) |
2. 详细对比
维度 | 实体类 | 边界类 | 控制类 |
---|---|---|---|
与用例的关系 | 被动参与用例,提供数据支持 | 直接对接参与者(如用户界面) | 驱动用例的执行,协调多类协作 |
技术依赖 | 依赖数据库或ORM框架 | 依赖UI框架、网络协议(如HTTP) | 通常与技术无关,依赖业务规则 |
生命周期 | 长期存在(如用户信息持久化存储) | 短期存在(如页面关闭后销毁) | 临时存在(如订单创建完成后释放) |
代码示例 | java<br>class User {<br> private String id;<br> private String name;<br>} |
java<br>class LoginPage {<br> public void showLoginForm() {}<br>} |
java<br>class OrderController {<br> public void createOrder() {}<br>} |
3. 协作关系
- 典型交互流程 (以"用户下单"为例):
- 边界类 (如
OrderPage
)接收用户输入(商品选择、地址等)。 - 控制类 (如
OrderController
)校验数据,调用实体类(User
、Product
)计算价格,生成Order
实体。 - 实体类 (
Order
)持久化数据到数据库。
- 边界类 (如
3.1.6
关键字 | 用途说明 |
---|---|
<<interface>> |
表示接口 |
<<abstract>> |
表示抽象类 |
<<include>> |
表示一个用例被另一个用例所包含 |
<<extend>> |
表示一个用例是对另一个用例的扩展 |
<<enumeration>> |
表示枚举类型 |
<<actor>> |
用例图中的参与者 |
<<singleton>> |
表示单例设计模式(非标准但常用) |
3.2 用例图
3.2.1 用例的编写
用例 是文本 形式的情节描述(是文本文档而不是图形),是一组成功和失败的场景集合,用来描述参与者如何使用系统来实现目标。
参与者 是具有行为的实物。
场景 是参与者和系统之间的一系列特定的活动和交互也称为用例实例(即下图的基本路径(主成功场景Happy Path)和扩展点(扩展场景,包含异常处理、分支选择等变体))

3.2.2 发现用例

3.2.3 用例图

左上角为用例的包含关系,右下角为泛化关系
3.2.4 用例命名
商品搜索×
搜索商品√
结账功能×
结账√
3.3 顺序图
- 顺序图(Sequence Diagram)是交互图的一种(交互图还包括协作图)
顺序图是强调消息时间顺序的交互图
协作图则是强调接收和发送消息的对象的结构组织的交互图 - 如何对动态方面建模?
所谓动态方面,即随着时间的推移,一些对象被创建,属性值的改变,以及其中一些对象的销毁,对象之间的互相调用!
对象
对象生命线
消息(实际上就是方法调用)
对象的创建与销毁
例子

注:在生命线上的小长方形条叫做,执行规格条(也叫激活条、控制条) ,表示控制期。
控制期就是对象处于"主动控制"状态的时间段,也就是说,它正在执行某个方法或在处理中。
一旦收到一个消息(比如 grade(answer)),控制开始;
执行完这个方法后,控制结束;
如果该对象在执行过程中还调用了其他对象的方法,会有嵌套的执行条出现。
3.4 状态图
3.4.1 基础

3.4.2 要素

3.4.3 示例(门禁卡)

3.4.4 历史状态

H*代表深度历史状态,即可以跳到任意一个活动状态,比如从暂停到选择。(图中是H)
3.5 活动图
3.5.1 基础

3.5.2 要素

3.5.3 相关概念
概览
部分概念的详细解释:




3.6 构件图

3.7 部署图
3.7.1 基础

3.7.2 示例

3.9系统顺序图SSD
3.9.1 定义
系统顺序图是用于描述系统的外部交互,通常用于捕捉系统和外部用户(或外部系统)之间的交互。它通常侧重于系统的边界,表现系统接收外部请求并作出响应的流程。
SSD与SD的区别:SSD主要注重操作与行为,主要展示系统与外部实体(例如用户或其他系统)之间的交互;SD主要注重消息,不仅显示外部与系统的交互,还可以包括内部对象间的消息传递
3.9.2 用途
对用例的主成功场景,以及频繁发生的或者复杂的替代场景绘制SSD
3.10数据流图DFD
3.10.1 基础
数据流图(DFD)是一种用于表示信息系统中数据流动情况 的图形工具。它通过图形方式,展示了系统中数据的输入、处理、输出和存储过程,不涉及具体的编程逻辑或控制流程。
它主要包括四个基本元素:
图形符号 | 元素名称 | 作用 |
---|---|---|
○ | 过程(Process) | 描述对数据的处理,如"计算总分" |
→ | 数据流(Data Flow) | 表示数据在各部分之间流动,如"学生信息" |
▭ | 数据存储(Data Store) | 表示静态数据存储,如"成绩数据库" |
□ | 外部实体(External Entity) | 表示系统外部的参与者或系统,如"教师"、"教务系统" |
3.10.2 类比
你可以把一个DFD图理解成一个快递流程图:
- 外部实体:比如"顾客"发出一个快递订单,这是一个外部输入。
- 数据流:快递单、包裹等信息在不同部门之间流动。
- 处理过程:快递公司收件、分拣、派送等环节都属于"处理过程"。
- 数据存储:快递公司的数据库中存储了订单信息,这就是"数据存储"。
整个过程不关注具体谁在操作(程序或人) ,而是关注数据从哪来,到哪去,中间做了什么处理。
3.11 交互图
包括顺序图(已讲)和通信图。
顺序图在绘图时,新增对象需要往右边扩展,不太方便;通信图加对象更灵活。但顺序图可以清楚表示消息顺序,通信图对顺序表达不够直观
3.12 常见符号
决策符号 (Decision):菱形
合并符号(Merge):表示多个选择路径最终归并为一条路径,也是菱形

耙子符号 (Fork/Join):表示"并行处理或合并处理"(fork表示分叉)
异步消息 :使用刺形箭头,就是→的直线穿过了折线的箭头,即
逻辑架构 是软件类的宏观组织结构。不涉及具体的实现技术、部署方式或运行时环境。
"软件类"指的是构成系统的各种模块、组件、类、服务等抽象单元。
你正在做一个自动阅卷系统,其逻辑架构可能包括以下模块
【阅卷系统逻辑架构】
├── 试卷管理模块
├── 答题识别模块(OCR)
├── 答案评估模块(AI/规则)
├── 分数汇总与反馈模块
├── 教师审阅模块
├── 用户身份与权限管理
四:九大模型(核心建模领域)
4.1 总结
UML模型通常按系统设计的不同维度分类,涵盖从需求到实现的完整生命周期:
-
结构模型
- 描述:系统静态结构(如类、组件、部署节点)。
- 关键图:类图、组件图、部署图。
-
行为模型
- 描述:动态交互与流程(如用户操作、状态变化)。
- 关键图:用例图、活动图、状态机图。
-
交互模型
- 描述:对象间消息传递(如接口调用、时序逻辑)。
- 关键图:序列图、通信图、时序图。
-
用例模型
- 描述:用户需求与系统功能边界。
- 关键图:用例图。
-
领域模型
- 描述:业务核心实体与规则(如MDA中的PIM)。
- 关键图:类图(领域类图)。
-
设计模型
- 描述:技术实现方案(如MDA中的PSM)。
- 关键图:类图(设计类图)、组件图。
-
部署模型
- 描述:软硬件部署架构(如服务器、容器配置)。
- 关键图:部署图。
-
组件模型
- 描述:模块化功能单元及其依赖。
- 关键图:组件图。
-
状态模型
- 描述:对象生命周期状态迁移。
- 关键图:状态机图。
4.5 领域模型(业务模型)
4.5.1 定义
领域模型(domain model),也称为概念模型、领域对象模型、分析对象模型,是对问题域中的对象及其关系的抽象描述,目的是帮助开发者更好地理解业务需求和业务规则。领域模型关注的是业务实体及其之间的关系,而不涉及具体的实现方式或软件架构。
软件类通常是面向实现的,它包含属性(数据)和方法(行为),领域模型不是软件类。
4.5.2 领域模型包括:
构建:寻找概念类 绘制uml图 添加关联与属性
概念:即名称
关联:指概念之间的业务关系
属性:指概念的详细特征或状态,描述实体的具体信息。
(领域模型是一种概念模型,不考虑方法)
4.5.3 例子

注:领域模型中关联用的是实直线,类图中用的是→
4.5.4 如何创建领域模型?
寻找概念类(名词短语、分析模式)绘制类图
添加关联和属性 属性的表示法
普通数据类型表示为属性
不要把复杂的领域概念建模为属性,建模为关联等就好
五:面向对象分析与设计OOA/D
5.1 介绍
面向对象分析object-oriented analysis :在问题域内发现和描述对象
面向对象设计object-oriented design:如何定义软件对象以及他们之间如何协作以实现需求
解释一下OO OOA OOD与OOP
OO(面向对象Object-Oriented) :面向对象(OO)指的是基于"对象"概念的编程范式,对象可以包含数据(属性)和代码(方法)。对象是类的实例,类定义了对象的结构(属性)和行为(方法)。
OOA(面向对象分析) :面向对象分析(OOA)是检查问题领域、识别对象(实体)并定义它们的关系和行为的过程。它专注于理解将要开发的系统的需求和约束。
OOP(面向对象编程Object-Oriented Programming) :面向对象编程(OOP)是紧随OOA之后的实施阶段。它涉及在支持对象和类的编程语言中编写代码。OOP允许编写模块化和可重用的代码,以及更准确地建模复杂的现实系统。
OOD(面向对象设计) :面向对象设计(OOD)是介于OOA和OOP之间的中间步骤。它涉及根据OOA的结果设计软件系统的架构。这包括定义类、它们的属性、方法和关系,同时考虑封装、继承和多态等原则。
总之,OOA专注于理解问题领域,OOD将分析转化为软件实现的设计,而OOP使用对象和类将这一设计转化为可执行代码。
5.2 Liskov Substitution Principle(LSP,里氏替换原则)
在使用基类(父类)的地方,应当能够透明地使用其子类的对象,而不影响程序的正确性。
你可以把"父类"看作是一种"通用契约",比如一个"鸟类"类。这个类中有一个 fly() 方法,代表鸟可以飞。那么你创建一个"子类"比如"麻雀(Sparrow)",继承"鸟类",它照样可以 fly(),没有问题。
但是,如果你创建一个"企鹅(Penguin)"子类,也继承了"鸟类",但企鹅不能飞。如果你还保留 fly() 方法,调用它会导致程序运行错误或语义混乱。这个时候,"企鹅"虽然是"鸟"的子类,但却不能替代"鸟"的对象来使用,这就违反了里氏替换原则。
5.3 开闭原则
软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
实现开闭原则的关键是通过抽象和多态来实现模块的可扩展性。常见的实现方式包括使用抽象类和接口定义可扩展的行为,然后使用具体的实现类来实现具体的行为。
5.4 层
层是对类、包或子系统的分组,具有对系统主要方面加以内聚的职责。
以评分系统为例:
【表示层】Presentation Layer
├── Web前端(教师/学生端)
├── RESTful API接口层
└── 处理请求路由、参数校验、认证
【业务逻辑层】Business Logic Layer
├── 阅卷控制器(GradingController)
├── 评分策略调度器(GradingStrategySelector)
│ ├── 简答题评分(LLM评分 + 规则引擎)
│ ├── 公式处理模块(Math Parser)
│ ├── OCR答案处理模块(图像转文本)
│ └── 多题型评分接口(选择题、填空题、主观题)
├── 成绩汇总与反馈生成模块
├── 权限与角色校验(教师/学生/管理)
【数据访问层】Data Access Layer
├── 考生与答案数据存储(AnswerRepository)
├── 试卷与题库存储(QuestionRepository)
├── 分数与报告存储(ScoreRepository)
oo系统通常包含的层有:用户界面层,应用逻辑层和领域对象层,技术服务层。分别负责交互、控制、业务建模与系统支撑。
六:开发的结构化框架
6.1 什么是RUP(Rational Unified Process)
RUP (rational统一过程)强调使用迭代和增量开发方法,旨在通过一系列预定义的阶段来管理软件项目的各个方面,包括需求、设计、编码和测试。
RUP的主要特点 包括:
迭代性 :项目被分成多个迭代周期(称为"阶段"),每个阶段都专注于特定的任务,如需求收集、设计、实现和测试。
增量性 :在每个迭代周期内,开发团队会完成一部分工作,并逐步向最终产品靠近。
可视化 :RUP使用各种图表和模型来描述软件项目的不同方面,如用例图、类图和序列图。文档化:RUP强调文档的重要性,要求团队在项目的各个阶段都生成相应的文档,以确保沟通和理解的一致性。
灵活性 :RUP允许项目团队根据项目的具体需求调整过程的某些方面,而不是强制使用一个固定的流程。RUP通常与UML(统一建模语言)结合使用,因为UML提供了一套标准化的图形表示法,可以帮助团队更好地理解和沟通软件的设计和结构。
6.2 RUP的四个阶段和九种工作流程
6.2.1 RUP的4个阶段
RUP将项目划分为四个顺序阶段,每个阶段以里程碑结束,强调迭代开发:
-
初始阶段(Inception)
- 目标:明确项目范围、可行性、核心需求和高层架构。
- 关键任务 :
- 定义业务目标和成功标准。
- 识别主要干系人和风险。
- 创建初步用例模型和项目计划。
-
细化阶段(Elaboration)
- 目标:建立稳定的系统架构,消除高风险问题。
- 关键任务 :
- 完善需求(用例细化)。
- 设计系统架构(如类图、组件图)。
- 构建可执行的原型验证架构。
-
构造阶段(Construction)
- 目标:通过迭代开发完成可交付的软件产品。
- 关键任务 :
- 编码实现功能模块。
- 持续集成和测试。
- 确保代码符合架构要求。
-
交付阶段(Transition)
- 目标:将产品部署到用户环境并完成验收。
- 关键任务 :
- 用户培训与文档编写。
- 修复遗留缺陷和性能优化。
- 正式发布并移交维护。
6.2.2 RUP的9种工作流程
RUP将开发活动划分为 6个核心工程流程 和 3个支持流程,贯穿整个项目周期:
核心工程流程
- 业务建模(Business Modeling)
- 分析业务目标、流程和规则,确保软件与业务对齐。
- 需求(Requirements)
- 收集、分析需求,通过用例(Use Case)描述功能场景。
- 分析与设计(Analysis & Design)
- 将需求转化为系统设计(类、接口、组件、架构)。
- 实现(Implementation)
- 编码、单元测试、构建可执行系统。
- 测试(Test)
- 验证功能、性能、可靠性(集成测试、系统测试等)。
- 部署(Deployment)
- 安装、配置软件,支持用户迁移和运维。
支持流程
- 配置与变更管理(Configuration & Change Management)
- 管理代码版本、变更请求和基线。
- 项目管理(Project Management)
- 规划、监控进度、风险和资源分配。
- 环境(Environment)
- 搭建开发工具链(IDE、测试工具等)和流程规范。
6.3
up核心思想:短时间定量迭代进化和可适应性开发
up阶段:初始inception细化elaboration构造construction移交transition
需求就是系统必须提供的能力和必须遵从的条件
需求按照FURPS+模型分类
furps+模型:功能性functional可用性usablity可靠性reliablity性能performance可支持性supportablity+实现接口操作包装授权
up需求制品:用例模型 supplementary补充性说明词汇表glossary设想vision业务规则
6.4 敏捷开发Agile Development
6.4.1 基础
敏捷开发 通常通过迭代和增量 的方式来进行项目管理与开发,主要过程如下:
迭代(Iterations):
- 计划阶段(Planning):确定每个迭代的目标、范围和优先级。
- 执行阶段(Execution):在每个迭代内进行设计、开发、测试和部署工作。
- 评审和回顾(Review and Retrospective):团队评估每个迭代的成果,查看进展和问题,并提出改进建议。
增量(Increments) :
每个迭代都产生一个完整的、可部署的软件增量,这意味着每个迭代都会将新功能或改进的功能集成到系统中,从而逐步完善产品。
增量式开发使得软件在每个迭代之后都有更多的功能可用,同时也更容易应对变化和客户需求的变更。

6.4.2 敏捷开发知识补充
敏捷开发 是一种以 快速响应变化 和 持续交付价值 为核心的软件开发方法。
核心理念
-
价值观(敏捷宣言):
- 个体与互动 > 流程与工具
- 可工作的软件 > 详尽的文档
- 客户协作 > 合同谈判
- 响应变化 > 遵循计划
-
原则:
- 迭代开发:短周期(2-4周)交付可运行的功能增量。
- 持续反馈:客户全程参与,快速验证需求。
- 自组织团队:扁平化管理,强调协作与自主决策。
- 简化设计:仅实现当前需求,避免过度设计。
客户协作优先
特点:
-客户作为团队成员全程参与,而非"甲方乙方"对立关系。(客户参与每日站会、迭代评审会,直接提供反馈)
-需求优先级可随反馈动态调整,合同条款保留灵活性(如按迭代付费)。
-价值:快速响应变化,交付真正解决用户问题的功能
常见方法
- Scrum :
用 Sprint (迭代周期)、Product Backlog (需求池)、每日站会 管理进度。 - Kanban (看板):
可视化工作流,限制在制品数量,优化效率。 - 极限编程(XP) :
强调 持续集成 、测试驱动开发(TDD) 、结对编程 等技术实践。
优势
- 快速交付:小步快跑,尽早提供可用功能。
- 降低风险:通过迭代验证需求,减少方向偏差。
- 灵活适应:需求变化可随时纳入后续迭代。
适用场景
- 需求不明确或频繁变化的项目(如互联网产品)。
- 需要快速试错、验证市场的创新业务。
- 团队协作紧密且追求高效沟通的环境。
6.4.3 RUP与敏捷开发
RUP强调文档和架构设计,但可通过裁剪(如减少文档)接近敏捷开发,属于"重型方法论"的灵活化应用。
1. 共同点
- 迭代式开发(Iterative Development)
- 两者均通过多次迭代(Iterations)逐步完善系统,而非一次性交付完整产品。
- 增量式交付(Incremental Delivery)
- 每个迭代交付部分功能(增量),逐步积累形成最终产品。
2. 核心差异
特性 | RUP | 敏捷开发(Agile) |
---|---|---|
本质定位 | 结构化过程框架(方法论) | 价值观与原则集合(如敏捷宣言) |
核心目标 | 控制复杂性和风险,强调文档化与架构设计 | 快速响应变化,专注于交付客户价值 |
灵活性 | 可裁剪但相对规范("重型方法论") | 高度灵活,轻量级(如Scrum、XP) |
流程规范性 | 定义明确的阶段、工作流程和工件(Artifacts) | 依赖具体实践(如Sprint、用户故事) |
文档要求 | 重视文档(用例、架构文档等) | 轻文档,强调可工作的软件和面对面沟通 |
适用场景 | 复杂系统、高风险项目(如金融、航天) | 需求变化频繁、创新性项目(如互联网产品) |
3. 迭代与增量的实现方式对比
RUP的迭代与增量
- 阶段化迭代 :
- 迭代分布于四个阶段(初始、细化、构造、交付),不同阶段迭代目标不同。
- 例如:细化阶段迭代聚焦架构验证,构造阶段迭代聚焦功能实现。
- 增量规划 :
- 增量通过用例(Use Case)或功能模块划分,但需严格遵循架构设计。
4. 敏捷开发的迭代与增量
- 均质化迭代 :
- 每个迭代(如Scrum的Sprint)目标一致:交付可工作的软件增量。
- 迭代周期固定(通常2-4周),持续反馈和调整优先级。
- 增量驱动 :
- 增量由用户故事(User Story)或最小可行功能(MVP)定义,直接对应客户价值。
用户故事 (User Story)是以用户为中心的需求描述方式,通过简洁的语言表达用户对系统功能的期望及其背后的价值。其核心格式通常为:
作为(角色),我希望(功能),以便(价值)。
示例:
"作为普通用户,我希望通过邮箱注册账户,以便快速开始使用平台的核心服务。"
最小可行功能 (Minimum Viable Feature, MVF) 是某个功能模块的最小实现版本,仅包含核心必要特性,旨在快速验证其可行性或用户接受度。即,仅实现核心功能,避免过度开发,通过用户反馈验证功能是否满足需求,后续逐步完善功能细节。它是最小可行产品 (MVP)的组成部分。示例:
在一个电商平台的MVP中,"支付功能"的MVF可能仅支持支付宝付款,而暂不包含信用卡、分期等复杂功能。
6.5 传统流程
6.5.1
传统"流程"通常指线性步骤(如瀑布模型),而RUP是框架性方法论,包含动态的、可裁剪的实践集合。
6.5.2 瀑布生命周期

七:设计模式
7.1 基础
OO设计原则 :GRASP和GoF(四人帮)设计模式,其建模基于职责驱动设计(RDD, Responsibility-Driven Design)
,即考虑怎样给协作中的对象分配职责,职责
指的是一个对象在系统中应该承担的角色和任务。RDD通过为每个对象明确分配职责,确保对象之间的交互(或协作)是自然且符合实际需求的
设计模式 是软件开发中常用的解决问题的方法和思想的总结。它们描述了在特定情境下如何解决重复出现的设计问题。设计模式不是具体的代码,而是一种通用的解决方案,可以应用于不同的情况。设计
强调的是满足需求的概念上的解决方案。实现
则表达了真实完整的设计。
7.2 GRASP原则
7.2.1 定义
GRASP (General Responsibility Assignment Software Patterns,通用责任分配软件模式)是一个面向对象设计的责任分配指导原则集,旨在帮助开发者在设计系统时,合理地将"责任"分配给合适的对象。它并非一个具体的设计模式,而是一组指导思想。
7.2.2 GRASP九大设计原则

.
- 创建者(Creator):
- 定义:负责创建另一个对象的类,通常是该对象的"容器"类或拥有该对象的重要数据的类。
- 含义:如果类A记录类B,或者A紧密使用B,或者A包含/组合/聚成B,或A拥有类B对象创建所需的信息,那么A应当负责创建B的实例。
- 示例:在客户端应用开发时,主程序创建一个窗口对象,由窗口对象来负责创建它内部的各种菜单,按钮,而不是由主程序创建完在设置到窗口里面去。
-
信息专家(Information Expert):
- 定义:将职责分配给拥有完成该职责所需信息的对象。
- 含义:当一个操作需要使用某些数据时,最合适的做法是将该操作分配给拥有这些数据的对象。这样可以减少对象之间的通信和耦合。
- 示例 :如果一个订单需要计算其总价,
Order
类就是一个信息专家,因为它包含了所有关于订单的必要信息。
-
低耦合(Low Coupling):
- 定义:尽量减少类之间的依赖关系,保持类之间的耦合度低。
- 含义:解决如何降低依赖性减少变化带来的影响,即提高重用性,就是去掉那些高度依赖于其他类的类,分配降低耦合性的职责,高耦合不是问题,问题是与不稳定元素的高耦合带来的不稳定性与不确定性(所以没人讲与JDK低耦合,因为JDK是稳定的)
- 示例:通过接口或抽象类来减少类与类之间的直接耦合。
-
高内聚(High Cohesion) :
-
控制器(Controller) :
-
多态(Polymorphism):
- 定义:通过多态性,类的不同子类可以实现相同接口的方法,从而使得代码能够以相同的方式操作不同类型的对象,实现为变化的行为类型分配职责。
- 示例 :在一个支付系统中,
CreditCardPayment
和PayPalPayment
可以都实现Payment
接口,而系统调用统一的processPayment()
方法。(解决如何处理基于类型的选择 如何创建可插拔的软件构件,当相关选择或行为随类型不同时,使用多态操作为变化的行为类型分配职责)
-
纯虚构(Pure Fabrication):
- 定义:为避免在设计时强迫一个对象承担不合适的职责,使用"纯虚构"模式引入一个额外的类来承担职责。
- 含义:纯粹虚构类并不直接对应任何业务实体(即不代表任何问题领域的概念),其解决不想违背高内聚低耦合,但是专家模式又不合适,该如何选择对象承担职责的问题,即虚构一种中介类,对该人为制造的类分配一组高内聚的职责,用以支持高内聚低耦合和复用。(所有的GOF设计模式都是纯虚构的)
- 示例 :一个
OrderFactory
类负责创建Order
对象,而不是将创建逻辑交给Customer
或Order
类。
-
间接性(Indirection):
- 定义:通过引入中介对象来避免直接交互,减少对象间的耦合。
- 含义:中介模式的应用可以将对象之间的依赖关系隔离,将职责分配给中介对象,将其作为其他构件或服务之间的媒介。
- 示例 :
Event
类通过一个EventManager
类来管理和通知不同的订阅者,而不是让Event
直接与每个订阅者进行交互。(大量GOF模式,如适配器,外观等,都是间接性的体现)
-
防止变异 protected variations :
一些补充:
可见性 :属性可见性,参数可见性,局部可见性,全局可见性若对象a能向对象b发送信息 则对于a而言b必须是可见的
若b是a的属性 则存在由a到b的属性可见性
若b作为参数传递给a的方法 则存在由a到b的参数可见性
若b被声明为a的方法内的局部变量 则存在由a到b的局部可见性
当b对于a是全局时 则存在由a到b的全局可见性
7.3 GoF

7.3.1 定义
GoF(Gang of Four)指的是 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides,他们在经典著作中整理了 23 个面向对象设计模式。这些模式被分为三大类:创建型(Creational)、结构型(Structural)、行为型(Behavioral)。
7.3.2 23 个面向对象设计模式
1. 创建型 (Creational)
模式 (中文 / English) | 意图 | C++ 代码示例 | 代码解释 |
---|---|---|---|
单例 Singleton | 仅允许一个实例并提供全局访问点 | cpp class Singleton{ public: static Singleton& instance(){ static Singleton s; return s; } private: Singleton()=default; Singleton(const Singleton&)=delete; }; | C++11 局部静态对象天然线程安全;构造与拷贝方法私有并且删除,确保唯一 |
工厂方法 Factory Method | 让子类决定实例化哪种产品 | cpp struct Product{virtual std::string name()=0;}; struct A:Product{std::string name()override{"A";}}; struct Creator{virtual std::unique_ptr< Product> create()=0;}; struct CreatorA:Creator{auto create()override{return std::make_unique();}}; | 客户端依赖抽象 Creator ;每个派生工厂返回不同具体产品 |
抽象工厂 Abstract Factory | 创建相关对象族且不指定具体类 | cpp struct Button{virtual void paint()=0;}; struct WinBtn:Button{void paint()override{}}; struct Checkbox{virtual void paint()=0;}; struct WinChk:Checkbox{void paint()override{}}; struct GUIFactory{virtual std::unique_ptr< Button> mkBtn()=0; virtual std::unique_ptr mkChk()=0;}; struct WinFactory:GUIFactory{auto mkBtn()override{return std::make_unique();} auto mkChk()override{return std::make_unique< WinChk>();}}; | 工厂接口统一生成"一家族"控件;具体工厂保证产品风格一致 |
建造者 Builder | 按步骤构造复杂对象 | cpp struct Meal{std::vector< std::string> parts; void add(std::string p){parts.push_back§;} }; struct Builder{virtual void partA()=0; virtual void partB()=0; virtual std::unique_ptr< Meal> result()=0;}; struct ConcreteB:Builder{std::unique_ptr< Meal> m=std::make_unique< Meal>(); void partA()override{m->add("Burger");} void partB()override{m->add("Drink");} auto result()override{return std::move(m);} }; | 将构造逻辑与产品分离;同一流程可产出不同配置 |
原型 Prototype | 通过克隆原型快速复制对象 | cpp struct Shape{virtual std::unique_ptr clone()const=0;}; struct Circle:Shape{int r; Circle(int r):r( r ){} auto clone()const override{return std::make_unique (*this);} }; | 复制已存在实例而非新建,避免依赖具体构造过程 |
注:
工厂:解决当为了改良内聚而分离创建职责时应该由谁来负责创建对象的问题,可以创建称为工厂的纯虚构对象来处理创建职责(有点类似GRASP的纯虚构,一种是改良现有设计,一种是在原有规则不适合的情况下的选择)(工厂的改变:简单工厂(静态方法或独立函数)->工厂方法->抽象工厂->依赖注入 / IoC 容器)
角色 | 作用 |
---|---|
抽象工厂(Abstract Factory) | 定义一组产品的创建接口(通常是抽象类或接口) |
具体工厂(Concrete Factory) | 实现抽象工厂接口,负责创建具体的产品族对象 |
🛠 实际应用举例:数据库驱动工厂
你写一个数据库访问层,可以定义抽象工厂:
javainterface DBFactory { Connection createConnection(); Statement createStatement(); }
然后具体工厂根据不同数据库来实现:
javaclass MySQLFactory implements DBFactory { public Connection createConnection() { return new MySQLConnection(); } public Statement createStatement() { return new MySQLStatement(); } } class PostgreSQLFactory implements >DBFactory { public Connection createConnection() { return new PostgreSQLConnection(); } public Statement createStatement() { return >new PostgreSQLStatement(); } }
客户端只需要拿到一个工厂,就可以一致地使用它:
javaDBFactory factory = new MySQLFactory(); // 或 PostgreSQLFactory Connection conn = factory.createConnection(); Statement stmt = factory.createStatement();
单实例类:解决单实例类的对象全局可见性和单点访问,可以对类定义静态方法以返回单实例,类似私有变量通过定义静态方法返回变量值。右上角角标1,表示仅能创建一个实例。
2. 结构型 (Structural)
模式 (中文 / English) | 意图 | C++ 代码示例 | 代码解释 |
---|---|---|---|
适配器 Adapter | 将现有接口转换为客户端期望接口 | cpp class Target{public: virtual void req()=0;}; class Adaptee{public: void specific(){} }; class Adapter:public Target,private Adaptee{void req()override{specific();}}; | 继承目标抽象并复用被适配者功能,实现接口兼容 |
桥接 Bridge | 分离抽象与实现,独立扩展 | cpp struct DrawAPI{virtual void circle(int)=0;}; struct OpenGL:DrawAPI{void circle(int)override{}}; class Shape{protected: std::shared_ptr< DrawAPI> api; public: Shape(std::shared_ptr< DrawAPI> a):api(a){} virtual void draw()=0;}; class Circle:public Shape{int r; Circle(int r,std::shared_ptr< DrawAPI> a):Shape(a),r®{} void draw()override{api->circle®;} }; | 抽象 Shape 与实现 DrawAPI 通过组合解耦;新增维度不互相影响 |
组合 Composite | 统一处理单个对象与组合 | cpp struct Component{virtual void op()=0; virtual void add(std::shared_ptr< Component>){} }; struct Leaf:Component{void op()override{}}; struct Composite:Component{std::vector<std::shared_ptr< Component>> kids; void add(std::shared_ptr c)override{kids.push_back©;} void op()override{for(auto&k:kids)k->op();}}; | Composite 递归聚合子节点,使客户端对叶/组合一视同仁 |
装饰 Decorator | 运行期动态附加职责 | cpp struct Coffee{virtual double cost()const=0;}; struct Simple:Coffee{double cost()const override{return 2;}}; struct Decor:Coffee{std::shared_ptr< Coffee> c; Decor(std::shared_ptr< Coffee> c):c©{} }; struct Milk:Decor{using Decor::Decor; double cost()const override{return c->cost()+0.5;} }; | 装饰对象持有被装饰对象指针,职责可层层叠加 |
外观 Facade | 提供统一入口简化子系统使用 | cpp class A{public:void fa(){}}; class B{public:void fb(){}}; class Facade{A a; B b; public:void op(){a.fa(); b.fb();}}; | 隐藏内部流程,客户端仅与高层接口交互 |
享元 Flyweight | 共享细粒度对象,节省内存 | cpp struct Glyph{char ch; Glyph(char c):ch©{}}; class Factory{std::unordered_map<char,std::shared_ptr< Glyph>> pool; public: std::shared_ptr< Glyph> get(char c){auto& g=pool[c]; if(!g) g=std::make_shared< Glyph>©; return g;} }; | 工厂使用哈希表缓存字符对象,多处重复使用同实例 |
代理 Proxy | 控制访问或延迟创建真实对象 | cpp struct Image{virtual void show()=0;}; struct Real:Image{std::string f; Real(std::string f):f(f){} void show()override{}}; struct Lazy:Image{std::string f; std::unique_ptr r; Lazy(std::string f):f(f){} void show()override{ if(!r) r=std::make_unique(f); r->show(); }}; | Lazy 仅在首次 show() 时才实例化 Real ,实现按需加载 |
注:
组合 :解决处理一组对象或具有组合结构的对象,可以定义组合和原子对象的类,使他们实现相同的接口
外观 :解决对一组完全不同的实现或接口需要公共统一接口的问题,可以使用外观对象封装子系统,外观对象提供唯一和统一的接口,并负责与子系统构件进行协作
适配器模式与其他结构型模式的关系:
模式 | 主要目的 | 与适配器的关系 / 差异 |
---|---|---|
适配器(Adapter) | 让两个原本不兼容的类协同工作 | 聚焦于接口不兼容的问题,强调接口转换 |
桥接(Bridge) | 将抽象和实现解耦,使它们可以独立变化 | 两者都用于解耦, 但桥接是预先设计 的双层抽象结构, 适配器是事后补救的转换器 |
装饰器(Decorator) | 动态扩展对象的功能,不改变原有对象 | 装饰器强调功能增强 ,不改变接口; 适配器强调接口变换,保持语义一致 |
代理(Proxy) | 控制对对象的访问(如懒加载、安全控制) | 代理和适配器都使用"包装"(wrapper), 但代理不改变接口 ,适配器改变接口 |
组合(Composite) | 统一对单个对象和组合对象的处理 | 可与适配器结合:适配旧结构后统一纳入组合结构中 |
外观(Facade) | 提供简化接口,隐藏复杂子系统 | 外观用于简化多个类的使用, 适配器用于解决接口不一致问题, 二者可联合使用 |
3. 行为型 (Behavioral)
模式 (中文 / English) | 意图 | C++ 代码示例 | 代码解释 |
---|---|---|---|
责任链 Chain of Responsibility | 多对象按链式顺序处理请求 | cpp class Handler{std::shared_ptr< Handler> next; public:void set(std::shared_ptr< Handler> n){next=n;} virtual bool handle(int lvl){return next?next->handle(lvl):false;}}; class H1:public Handler{bool handle(int lvl)override{return lvl<=1?true:Handler::handle(lvl);} }; | 每个处理者决定是否处理,否则转交给下一节点,实现解耦 |
命令 Command | 将请求封装为对象 | cpp struct Rec{void act(){}}; struct Cmd{virtual void exe()=0;}; struct Concrete:Cmd{Rec& r; Concrete(Rec& r):r®{} void exe()override{r.act();}}; | 将操作与接收者封装为命令对象,支持撤销、排队等 |
迭代器 Iterator | 提供遍历聚合的统一接口 | cpp template< typename T> struct Agg{std::vector v; void add(T x){v.push_back(x);} auto begin(){return v.begin();} auto end(){return v.end();}}; | 封装 begin/end ,使客户端可用范围 for 遍历 |
中介者 Mediator | 封装同事对象间通信 | cpp struct Col; struct Med{virtual void send(const std::string&,Col*)=0;}; struct Col{Med& m; Col(Med& m):m(m){} virtual void notify(const std::string&)=0;}; struct MedC:Med{Col c1,c2; void set(Col a,Col b){c1=a;c2=b;} void send(const std::string& msg,Col* s)override{(sc1?c2:c1)->notify(msg);} };== | 所有消息通过中介转发,减少对象之间直接耦合 |
备忘录 Memento | 捕获并恢复对象状态 | cpp class Originator{int st;public:struct Mem{int s;}; void set(int s){st=s;} Mem save()const{return{st};} void load(const Mem& m){st=m.s;} }; | 备忘录保存内部状态;外界可回滚而不破坏封装 |
观察者 Observer | 状态变化时通知依赖者 | cpp struct Obs{virtual void up(int)=0;}; struct Sub{int st=0; std::vector<Obs*> os; void att(Obs* o){os.push_back(o);} void set(int s){st=s; for(auto* o:os) o->up(st);} }; | Sub 变化时遍历调用 Obs::up ,实现发布/订阅 |
状态 State | 对象在状态改变时改变行为 | cpp struct C; struct S{virtual void h(C&)=0;}; struct C{std::unique_ptr< S> s; C(std::unique_ptr< S> s)😒(std::move(s)){} void req(){s->h(*this);} void set(std::unique_ptr n){s=std::move(n);} }; struct SA:S{void h(C& c)override{c.set(std::make_unique< SB>());} }; struct SB:S{void h(C& c)override{c.set(std::make_unique< SA>());} }; | 具体状态类更改上下文所持状态对象,实现行为切换 |
策略 Strategy | 定义可互换算法族 | cpp struct Strat{virtual void sort(std::vector< int>&)=0;}; struct Quick:Strat{void sort(std::vector< int>&)override{/.../}}; struct Ctx{std::unique_ptr< Strat> s; Ctx(std::unique_ptr< Strat> s): s(std::move(s)){} void sort(std::vector< int>& v){s->sort(v);} }; | 算法封装为对象并注入上下文,运行期可替换 |
模板方法 Template Method | 定义算法骨架,将可变步骤留给子类 | cpp class Game{public:void play(){init(); while(!over()) turn(); finish();} protected:virtual void init()=0; virtual void turn()=0; virtual bool over()=0; virtual void finish()=0;}; | 流程固定在基类 play() ;子类实现具体步骤 |
访问者 Visitor | 在不修改类的前提下为结构加新操作 | cpp struct Circle; struct Rect; struct Visitor{virtual void v(Circle&)=0; virtual void v(Rect&)=0;}; struct Shape{virtual void acc(Visitor&)=0;}; struct Circle:Shape{void acc(Visitor& vi)override{vi.v(this);}}; struct Area:Visitor{void v(Circle&)override{/ .../} void v(Rect&)override{/...*/}}; | 结构元素通过 accept() 将自身传入访客,实现操作集中管理 |
八:Rational Rose
◇ Rational Rose 是一种建模工具
◇ 用例视图
需求分析阶段的利器
◇ 逻辑视图
设计阶段,用例的实现
◇ 组件(构件)视图
构件表示封装了其内容的系统模块;构件是相对独立的模块
◇ 部署视图
表示软件元素在物理架构上的部署,以及物理元素之间的通信

九:实战
题目
请根据以下描述,画出相应的UML图:
◇ 神州六号飞船是神州飞船系列的一种,它由轨道舱、返回舱、推进舱和逃逸救生塔等组成;航天员可以在返回舱内驾驶飞船,轨道仓则是航天员工作和休息的场所。在紧急的情况下,可以利用逃逸救生塔逃生。在飞船两侧有多个太阳能电池翼,可以为飞船提供电能:

4.1 正向工程、逆向工程与MDA
- 正向工程:从UML图形生成JAVA代码
- 逆向工程:从JAVA代码生成UML图形
- 不要依赖于正向或逆向工程!仅是一种辅助手段。画图的目的不是为了生成代码!写代码的目的也不是为了生成图形!
- MDA?
模型驱动架构
Platform IndependentModels (PIMs)和 Platform Specific Models (PSMs)
MOF---(UML>元模型>元---元模型)
二、十三类图(UML 2.x标准图表)
UML 2.x定义了13种标准图表,分为结构图 与行为图两大类:
1. 结构图(静态结构)
图表名称 | 核心用途 | 示例场景 |
---|---|---|
类图 | 定义类、接口、关联与继承关系 | 领域模型、数据库设计 |
对象图 | 展示类在某一时刻的实例化状态 | 调试对象关系、快照分析 |
组件图 | 描述系统模块化组件及其接口依赖 | 微服务架构设计、模块划分 |
部署图 | 展示软硬件节点部署及通信路径 | 云环境部署、服务器拓扑规划 |
包图 | 组织代码包层级与依赖关系 | 项目模块化管理、代码分包 |
组合结构图 | 描述复杂类的内部结构(如部件协作) | 复合组件设计、子系统集成 |
2. 行为图(动态交互)
图表名称 | 核心用途 | 示例场景 |
---|---|---|
用例图 | 定义用户目标与系统功能边界 | 需求分析、功能范围确认 |
活动图 | 描述业务流程或算法逻辑(类似流程图) | 订单处理流程、审批流程建模 |
状态机图 | 展示对象状态迁移及触发事件 | 订单状态机、设备生命周期管理 |
序列图 | 按时间顺序描述对象间消息交互 | API调用时序、事务处理逻辑 |
通信图 | 强调对象协作关系(类似序列图但侧重结构) | 分布式系统交互、角色职责划分 |
时序图 | 结合时间约束展示状态变化时序 | 实时系统设计、硬件信号时序分析 |
交互概览图 | 组合活动图与交互图的复合视图 | 复杂交互流程的全局概览 |

八:附录
附录一:图形表示一览