ELEC5620 Week 06 结构建模(下):复杂结构讲课总结
ELEC5620 Week 06 讲课总结:Modeling Structure(Part 2)—— Complex Structure
课程:ELEC5620 — Model Based Software Engineering,Semester 2 2026 讲师:Dong Yuan 来源:讲义 PDF
5 Modeling Structure part 2.pdf(33 页)+ELEC5620-TUT-06.pdf(22 页)+ELEC5620-Lab-Note-6.pdf(1 页)。本周无转录稿。本周覆盖: 1. 基础结构概念练习(承接 Week 5) 2. 为什么类图不够:运行时配置的多义性、对象图的局限 3. 角色与协作:MicroHamlet、Collaboration Use、协作继承 4. 结构化类:端口、接口、内部结构、结构精化 5. Agentic AI 中的对象图、协作和结构化类 6. Tutorial 6:对象图记号与画法 + 行为建模预告;Lab 6:对象图
相关笔记:Week 05 架构模式与结构建模(上)|Lab 1–6 总结
一、承接:基础结构概念练习
讲义开头给出 Week 5
Adult (parents 1..2) —— (children 0..*) Child
类图上的练习。
| 题目 | 解答思路 |
|---|---|
Karl 的 children
集合是什么? |
沿着 Karl
的所有链接,取另一端(children 端)的对象构成集合。讲义 OCL
例子 Karl.children->includes(Cory) 说明 Cory
在其中;完整集合按 Week 5 图中从 Karl 出发的链接逐个读出。 |
Cory 的 parents
集合是什么? |
反向读:所有以 Cory 为
children 端的链接,取 parents 端的对象;多重性
1..2 保证集合有 1 或 2 个元素。 |
| 为什么 Association 是 classifier? | 分类器 =
对一组共享特征、并可按特征进一步划分的实体的规格。关联规格了一组链接(共享特征:各端类型相同);链接可以按特征再分类——即关联特化(如
C-accounts 特化
accounts);而且关联可以作为链接的类型。三点都满足分类器的定义。 |
| 扩展类图,显式表示 Adult 与儿子、Adult 与女儿的关系 | 用泛化集 +
关联特化:Child 按 gender 泛化集分出
Son、Daughter;增加两条关联
Adult —— sons: Son [0..*] 和
Adult —— daughters: Daughter [0..*],端点标注
{subsets children},对应的父母端标
{subsets parents};原 children 端可标
{union}。 |
classDiagram
class Adult
class Child
class Son
class Daughter
Child <|-- Son
Child <|-- Daughter
Adult "1..2 parents" -- "0..* children" Child
Adult "1..2" -- "0..* sons {subsets children}" Son
Adult "1..2" -- "0..* daughters {subsets children}" Daughter
二、为什么需要复杂结构建模
2.1 五岁小孩与计算机科学家
问题:画一辆车。
- 计算机科学家画的是类图式的抽象(Car 有 4 个 Wheel……)
- 五岁小孩画的是:方框代表部件,线代表部件之间的某种连接——Left Front Wheel、Right Front Wheel、Engine、Body、Left/Right Rear Wheel 按实际位置摆放并连线
Taking a cue from the 5-year old:架构建模更需要“部件 + 连接”的直观表示——这就是结构化类的思路。
2.2 问卷:一个类图描述多少种运行时配置?
类图:ClassA 与 ClassB 之间有两条关联,A
端角色 al、ar,B 端角色
left、right,多重性都是 1。
可能的运行时配置:
| 配置 | 结构 |
|---|---|
| (1) | a1:ClassA 通过 left 和 right
两条链接都连到同一个 b1:ClassB |
| (2) | a1 的 left 连
b1,b1 的 right 连
a2,a2 的 left 连
b2,b2 的 right 连回
a1……形成环 |
| (3) | 等等——环可以任意长 |
答案:不止一种,实际上有无穷多种。类图只约束“每个对象恰好有一个 left 和一个 right”,并不规定它们构成怎样的拓扑。
2.3 Node 例子
类 Node 有自关联 left 0..1 和
right 0..1。同一个类图既能描述一棵二叉树
N1 → {N2, N4}, N2 → N3,也能描述一条链
N1 → N2 → N3。
结论:类图并不总能精确表示运行时结构;有些结构需要在实例层次表示。
2.4 对象图?不一定
- 对象图表示某个具体系统在某一时刻的“快照”
- 只能作为例子,不能作为一般的架构规格(除非定义 profile)
- 例:时刻 T 是 N1–N4,时刻 T+1 多了 N5——两张对象图都只是瞬间
⇒ 需要一种方式来描述跨时间的“原型实例(prototypical instances)”。答案是角色(roles)。
三、角色与协作
3.1 角色:原型实例
Role:在某个更广泛的上下文(协作)中,承担特定职责的实例的表示。
- 例:莎士比亚剧中的 Hamlet 这个角色
- 可以由不同的实际个体(实例)来扮演:Laurence Olivier、Kenneth Branagh 都演过 Hamlet
- 角色记号
Hamlet : YoungMan——角色名 + 类型约束
3.2 协作
Collaboration:描述一组协作的角色,它们通过连接器(connectors,表示通信链接)通信。
MicroHamlet 协作:
┌──────────────── MicroHamlet ────────────────┐ |
Hamlet : YoungMan是受约束的角色(必须由 YoungMan 扮演)Ghost是无约束的角色- 线是连接器
协作 = 一个协作对象实例网络,但对象的身份被抽象掉了(只剩角色)。
| 演出 | Gertrude | Ophelia | Hamlet | Ghost |
|---|---|---|---|---|
| MicroHamlet (1948) | E. Herlie | J. Simmons | L. Olivier | L. Olivier |
| MicroHamlet (1996) | J. Christie | K. Winslet | K. Branagh | B. Blessed |
两个观察:同一个实例可以扮演不同角色(1948 年 Olivier 同时演 Hamlet 和 Ghost);同一个角色可以由不同实例扮演(Olivier 和 Branagh 都演 Hamlet)。具体演出与协作之间是
«abstraction»关系。
记号:教科书里常见用虚线椭圆画协作,但空间利用率低,讲义推荐矩形记号。
3.3 Collaboration Use(协作使用)
把一个协作规格应用到另一个结构中:
Sale 协作:Buyer —— Seller |
wholesale : Sale和retail : Sale是两次协作使用;broker在一次里是 Buyer、在另一次里是 Seller。
3.4 协作是分类器
- 协作可以通过继承来精化 ⇒ 可以定义通用架构结构
- 例:
TwoViewMVC(ctrlr、model、view1、view2)被ThreeViewMVC继承并加上view3
四、结构化类(Structured Classes)
4.1 概念
结构化类 = 具有外部结构(端口交互点)和内部(协作)结构的类;主要用于架构建模。
- 渊源:架构描述语言(ADL)——UML-RT profile(Selic & Rumbaugh, 1998)、ACME(Garlan et al.)、SDL(ITU-T Z.100)
- 直觉:“打开”一个类,看它的组件在运行时如何连线
Tutorial 6 的总结图:
| 外部结构 | 内部结构 |
|---|---|
| Ports:命名的交互点 | Parts and connectors:内部组件和通信路径 |
| Interfaces 描述端口提供或需要的服务 |
4.2 端口
- 对象可以有多个交互点,每个专用于特定目的(如数据库对象有 Admin 端口 和多个 User 端口)
- Port 结构模式:对象为多个(可能同时进行的)协作提供不同的交互点;端口让对象区分不同的外部协作者,而不直接耦合到它们
讲义例子:objM 的方法里写
q.setA(d)(通过端口 q 发送),而不是
objM.setA(d) 直接引用某个对象——objM
不需要知道端口另一端连的是 objC 还是 objG。
4.3 端口与接口
- 端口可以提供(provided)和/或需求(required)接口;一般情况两者兼有,单向端口也很常见
DataBase 例子:
| 端口 | 接口 | 方向 |
|---|---|---|
adminPort /
clientPort |
«interface» DBserver { readDB(recNo), writeDB(recNo, d), notifyOfChange(recNo) } |
Provided(lollipop) |
clientPort |
«interface» DBclient { change(d) } |
Required(socket,«uses») |
一个端口多个接口?可以,但应避免:
- 会产生名字冲突(如
WebServer.read(id)与Library.read(id)),需要消歧机制 - 如果接口附带协议状态机,语义不清
- 为每个接口定义单独的端口问题少得多
端口的一个基本目的就是“角色分离”!
4.4 内部结构
- 结构化类可以包含由 parts 组成的协作结构,part 是其他结构化类(或基本类)的用法
- 例:
ClassX内部有partF : F,ClassX的外部端口通过委托连接器(delegation connector)连到内部 part 的端口 - 讲义问:类的所有属性都应该成为结构化类中的 part 吗? —— 不。只有那些在运行时作为协作组件、需要连线的才作为 part;普通数据值(如 name: String)仍是属性。
4.5 使用结构化类
- 结构化类可以把复杂的架构结构作为一个单元来捕获
- 可以作为一个单元被创建和销毁
- 例:
FaxCall内部有sender : Fax和receiver : Fax,两者的remote端口相连;FaxCall的sendCtrl、receiveCtrl端口分别委托到两者的c端口
4.6 通过特化精化结构
- 架构层面的复用;适合表示产品族(产品线)
ProductArchitecture(sender、receiver)→ProductA(照搬)、ProductB(加入mgr : FaxMgr)
这和 Week 3 的 feature model / 产品线 相呼应:特征模型描述“产品之间有什么差异”,结构化类的特化描述“架构上如何实现这些差异”。
五、Agentic AI 中的复杂结构
5.1 Agentic AI 对象图的关键元素
对象图用来说明 AI agent 在运行时如何被实例化。以 BDI 建模时,对象通常包括:
| 类别 | 例子 |
|---|---|
| Agent 实例 | DoctorAgent1 |
| Belief 对象 | KnowledgeBase、UserProfile |
| Desire/Goal 对象 | BookAppointment |
| Intention/Plan 对象 | SendReminder |
| Environment 对象 | HospitalSystem |
要分析同一个类的多个对象之间的关系:一个 agent 对象有多个 beliefs,一个 belief 关联多个 agents。
5.2 讲义例子:两个 doctor agent 共享 belief
flowchart TB
G1["bookAppointment1 : Goal<br/>status = pending"]
G2["bookAppointment2 : Goal<br/>status = pending"]
HK["hospitalKnowledge : Belief<br/>type = KnowledgeBase"]
PP["patientProfile : Belief<br/>type = UserProfile"]
D1["doctorAgent1 : DoctorAgent"]
D2["doctorAgent2 : DoctorAgent"]
P1["scheduleVisit1 : Plan<br/>status = executing"]
P2["scheduleVisit2 : Plan<br/>status = executing"]
HS["hospitalSystem : HospitalSystem"]
D1 -- desires --> G1
D2 -- desires --> G2
D1 -- has belief --> HK
D2 -- has belief --> HK
D1 -- has belief --> PP
D2 -- has belief --> PP
D1 -- intends --> P1
D2 -- intends --> P2
P1 -- pursues --> G1
P2 -- pursues --> G2
D1 -- operates in --> HS
D2 -- operates in --> HS
每个 agent 有两个 belief;每个 belief 关联两个 agent。 Tutorial 的快速检查题:两个 agent 共享同一个 Belief 对象,要画几个 Belief 框?—— 一个。 对象图里一个对象只画一次,多个链接连到它;画两个框就变成了两个不同身份的对象。
5.3 Agentic AI 中的协作:预约
场景:患者与 booking agent 沟通,agent 确认医生是否有空。
协作 Booking Appointment: |
注意 Patient 和 Doctor 是同一个类型 User 的不同实例扮演不同角色——这正是角色比类更适合描述协作的原因。
5.4 Agentic AI 中的结构化类:HealthcareAgent
Agent 是复杂的软件实体,有子组件:Belief Base(知识、记忆)、Desire/Goal Manager、Intention/Plan Manager、Reasoning/Decision Engine、Communication Interface。结构化类图描述这些部分如何在内部组织和交互。
┌──────────────────────── HealthcareAgent ────────────────────────┐ |
- 外部:
PatientCommPort(面向患者)和HospitalAPIPort(面向医院系统)——两个端口,两种角色 - 内部:四个 part 通过连接器连线;
Reasoner从 BeliefBase 和 GoalManager 推理,再把 intention 交给IntentionHandler执行
六、复杂结构建模小结
| Collaborations | Structured classes(和 components) | |
|---|---|---|
| 用途 | 捕获协作对象的模式 | 架构组件 |
| 组成 | 角色、连接器 | 外部结构(端口)+ 内部结构(parts、connectors) |
| 封装 | 没有封装外壳,不能作为对象实例化 | 可以作为一个单元创建和销毁 |
UML 引入 structured classifiers 主要就是为了架构建模。
七、Tutorial 6 要点与解答思路
7.1 对象图记号
- 对象标签:
objectName : ClassName(整体加下划线);匿名对象写: ClassName - 属性槽:显示此刻的值(
status = active、mode = assisting) - 链接 = 实线;链接名表示含义(has belief)
- 关联连接类,链接连接对象实例
7.2 对象图 vs 类图(常考对比)
| Class Diagram | Object Diagram | |
|---|---|---|
| 分栏 | 三栏:名称、属性、操作 | 两栏:名称、属性 |
| 名称 | 只写类名 | 对象名 : 类名 或
: 类名(下划线) |
| 属性 | 列出所有特性(类型) | 定义属性的当前值 |
| 连接 | 关联:有名称、角色、多重性、约束 | 链接:有名称和角色,但没有多重性(每条链接都是一对一) |
| 表示 | 对象的分类 | 个体实体 |
7.3 画对象图的七步
- 识别类:确定场景相关的类
- 识别对象:每个类要包含哪些具体实例
- 画对象框:写对象名
- 加属性和值
- 画关系:用线连接对象,必要时用箭头表示方向
- 标注关系:用动词或短语
- 审查与精化
Tutorial 示例(PDF 中为图片):University Department、Order System(类图到对象图)、Company Structure、POS、Writer、Robot Moving Behavior、类似通信图的对象结构。
7.4 行为建模预告(Tutorial 6 后半)
- 行为建模描述系统的动态行为:对象如何交互、执行动作,系统如何响应事件
- 关键元素:Actions、Activities、Interactions、State Machines
- Actions 和 Activities 用于微观行为;State Machines 和 Interactions 捕获宏观行为
- Action:活动中的单个原子步骤,不再分解;类型包括通信动作、对象动作、链接动作、结构特性动作、变量动作;例:create link、write attribute、destroy object
(详见 Week 7。)
八、Lab 6 要点
ELEC5620-Lab-Note-6.pdf(文件头 “Week 7: Laboratory
6”):
- Step 1:回顾已有类图,识别需要实例化的关键类;为每个类创建实例,给出具体名字和属性值
- Step 2:用结构建模技术画对象图,展示运行时实例和关系,重点展示对象之间的协作(如何交互和通信)
做 Lab 6 的检查点(结合本周讲义):
- 对象名必须是
name : Class,并和类图里的类对应 - 链接必须对应类图里存在的关联,数量不违反多重性
- 共享对象只画一次(如共享的 Memory/Belief/KnowledgeBase)
- 选一个具体场景(某个 use case
运行到某一时刻),属性值要反映那一刻(如
status = executing) - 想表达“不依赖具体实例的协作模式”时,用协作 + 角色而不是对象图
更多常见失分点见 Lab 1–6 总结 第七节。
九、本周考点速记 / 易错点
- 类图不足以精确描述运行时结构:同一类图可对应无穷多种运行时配置(A/B 环、Node 树或链)。
- 对象图只是快照,不能作为一般架构规格。
- 角色 = 原型实例:在协作中承担职责;同一实例可扮演多个角色,同一角色可由不同实例扮演。
- 协作 = 角色 + 连接器;对象身份被抽象掉;不能被实例化;是分类器,可继承(TwoViewMVC → ThreeViewMVC);可通过 collaboration use 应用(BrokeredSale)。
- 结构化类 = 端口(外部)+ parts/connectors(内部);可作为单元创建销毁;渊源是 ADL(UML-RT、ACME、SDL)。
- 端口:让对象区分外部协作者而不直接耦合;可提供/需求接口;一端口一接口(避免名字冲突、协议状态机语义不清);端口的基本目的是角色分离。
- 委托连接器把外部端口连到内部 part;不是所有属性都要变成 part。
- 结构特化用于产品族。
- Agentic 对象图:Agent、Belief、Goal、Plan、Environment 对象;共享对象只画一个框。
- 对象图 vs 类图:两栏 vs 三栏;下划线对象名;链接无多重性。
- 易错:在对象图里写多重性;对象名不加下划线或缺类名;把协作画成对象图;同一个 agent 的端口混用多个接口。