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 ────────────────┐
│ Gertrude : OlderWoman ─── Ophelia : YoungWoman │
│ \ / │
│ Hamlet : YoungMan │
│ │ │
│ Ghost ← unconstrained role(无类型约束)│
└─────────────────────────────────────────────┘
  • 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

BrokeredSale 协作:
producer ──(wholesale : Sale)── broker ──(retail : Sale)── consumer
wholesale 中:producer 扮演 Seller,broker 扮演 Buyer
retail 中:broker 扮演 Seller,consumer 扮演 Buyer

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»)

一个端口多个接口?可以,但应避免:

  1. 会产生名字冲突(如 WebServer.read(id) 与 Library.read(id)),需要消歧机制
  2. 如果接口附带协议状态机,语义不清
  3. 为每个接口定义单独的端口问题少得多

端口的一个基本目的就是“角色分离”!

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:
Requester : User ── Mediator : Booking Agent ── Provider : User

协作使用 BA1 : Booking Appointment:
Patient1 : User 扮演 Requester
Agent1 : Booking Agent 扮演 Mediator
Doctor1 : User 扮演 Provider

注意 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 ◻
│ │ Input CallAPI │ │
│ ▼ │ │
│ Reasoner : DecisionEngine ──Execute Intention──▶ IntentionHandler : PlanExecutor │
│ ▲ Belief Reasoning Goal Reasoning ▲ │
│ │ │ │
│ BeliefBase : KnowledgeStore GoalManager : DesireManager │
└──────────────────────────────────────────────────────────────────┘
  • 外部: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 画对象图的七步

  1. 识别类:确定场景相关的类
  2. 识别对象:每个类要包含哪些具体实例
  3. 画对象框:写对象名
  4. 加属性和值
  5. 画关系:用线连接对象,必要时用箭头表示方向
  6. 标注关系:用动词或短语
  7. 审查与精化

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 的检查点(结合本周讲义):

  1. 对象名必须是 name : Class,并和类图里的类对应
  2. 链接必须对应类图里存在的关联,数量不违反多重性
  3. 共享对象只画一次(如共享的 Memory/Belief/KnowledgeBase)
  4. 选一个具体场景(某个 use case 运行到某一时刻),属性值要反映那一刻(如 status = executing)
  5. 想表达“不依赖具体实例的协作模式”时,用协作 + 角色而不是对象图

更多常见失分点见 Lab 1–6 总结 第七节。


九、本周考点速记 / 易错点

  1. 类图不足以精确描述运行时结构:同一类图可对应无穷多种运行时配置(A/B 环、Node 树或链)。
  2. 对象图只是快照,不能作为一般架构规格。
  3. 角色 = 原型实例:在协作中承担职责;同一实例可扮演多个角色,同一角色可由不同实例扮演。
  4. 协作 = 角色 + 连接器;对象身份被抽象掉;不能被实例化;是分类器,可继承(TwoViewMVC → ThreeViewMVC);可通过 collaboration use 应用(BrokeredSale)。
  5. 结构化类 = 端口(外部)+ parts/connectors(内部);可作为单元创建销毁;渊源是 ADL(UML-RT、ACME、SDL)。
  6. 端口:让对象区分外部协作者而不直接耦合;可提供/需求接口;一端口一接口(避免名字冲突、协议状态机语义不清);端口的基本目的是角色分离。
  7. 委托连接器把外部端口连到内部 part;不是所有属性都要变成 part。
  8. 结构特化用于产品族。
  9. Agentic 对象图:Agent、Belief、Goal、Plan、Environment 对象;共享对象只画一个框。
  10. 对象图 vs 类图:两栏 vs 三栏;下划线对象名;链接无多重性。
  11. 易错:在对象图里写多重性;对象名不加下划线或缺类名;把协作画成对象图;同一个 agent 的端口混用多个接口。