软件建模15:四种 archetype
设备 E1 和 E2 都属于 CAM-A 型号,但租出 E1 不能让 E2 一起变成已出租。P1 同时办理租赁和验收,结束经办任职也不能删除这个人的验收职责。如果只按几个相似名词建立类,实物、共享描述、业务角色与一次租赁约定很容易混在一起。
四色建模用四种 archetype 提醒建模者检查这些区别。本篇把它们作为租赁模型的候选分类,用真实对象操作检验身份和历史是否丢失。颜色不参与程序判断,也不替模型选择数据库表、聚合或不可变类型。
四种语义如何进入租赁案例
四种 archetype 通常以粉色 Moment-Interval、黄色 Role、蓝色 Description、绿色 Party-Place-Thing 表示。出版社第 5 章的实例提供了核对入口:项目及活动请求是粉色,承担职责的角色是黄色,请求池是绿色;账户示例还区分粉色汇率事实与蓝色货币对描述。出版社原章,§5.1.1、§5.2.1,印刷页157、167
应用到本系列时,分类需要回答具体问题。Moment-Interval 关注一次值得保留的业务发生或期间;Role 表达对象在某种关系中的职责;Description 提供可共享的描述;Party-Place-Thing 表达参与方、地点或事物。表中的对应全部是教学选择,没有声称原书给出了这套设备租赁实现。
| 候选概念 | 本例 archetype | 必须保留的区别 |
|---|---|---|
| 租赁约定 A1 | 粉色 Moment-Interval | 一次约定及其期间 |
| O1 的经办任职 R1 | 黄色 Role | P1 在指定组织的职责 |
| 设备 E1 | 绿色 Party-Place-Thing | 一台可区分的实物 |
| 型号 CAM-A 的描述 | 蓝色 Description | 多台设备共享的说明 |
这里的“期间”不是一个日期字段。设备也可能保存购买日期,型号也可能保存发布日期,但存在日期不足以决定粉色分类。A1 表达的是一次具体租赁约定,起止时刻直接界定该次业务事实;E1 则会参与许多不同的约定,跨越它们继续存在。
一张图里的颜色与关系
flowchart LR
D["蓝色 Description:CAM-A 型号描述"] --> E["绿色 Party-Place-Thing:设备 E1"]
P["绿色 Party-Place-Thing:参与方 P1"] --> R["黄色 Role:O1 经办任职 R1"]
R --> A["粉色 Moment-Interval:租赁约定 A1"]
E --> A
classDef pink fill:#f8c8dc,stroke:#71334b,color:#222;
classDef yellow fill:#fff0a8,stroke:#756319,color:#222;
classDef green fill:#c8edcc,stroke:#32633a,color:#222;
classDef blue fill:#c9e2ff,stroke:#355b80,color:#222;
class A pink;
class R yellow;
class P,E green;
class D blue;
图是当前教学候选的关系视图。箭头表示阅读方向,不表示消息调用、对象所有权或精确多重性。节点同时写出语义名称,因此黑白打印也能理解。图没有照搬未核对的原书第 1 章关系模板,不据此规定每个类必须拥有四种颜色的邻居。
设备 E1 指向 CAM-A 第一版描述,E2 也指向同一份描述。描述的共享不妨碍实物分别出租,正如参与方 P1 可以关联两条任职而不产生两个不同的人。11 篇的类型对象讨论已经给出相邻问题,这里增加的是语义分类及其反例,而不是另一套库存系统。
把描述当实物会丢掉什么
实验从 JSON 夹具创建 E1、E2 两个设备对象,它们共享一个 ModelDescription。按设备编号建立索引,保留两项;错误候选按型号编号建立索引,后写入的 E2 覆盖 E1,索引只剩一项。这是实际字典操作的结果,不能用“绿色表示实体”一句话替代。
丢失的不是重复说明,而是一台实物的身份。如果后续登记 E1 的维修状态,错误索引连 E1 都无法定位。反过来,若把型号说明复制进每台设备,虽然暂时保留身份,改说明时又要决定哪些副本应同步。本例共享描述并保留实物编号,分别承担两个查询。
地点也可作同样的语义走查。门店 S1 是一个需要区分的位置,门店类型“自提点”则是可共享描述;A1 的取机地点应该引用 S1,不能只保存“自提点”三个字。否则多个门店属于相同类型时,无法确定设备应送到哪里。这是本章的书面变化例,没有进入当前实验,也没有据此宣称已实现配送。
相反,业务只需要显示一段取机说明、不需要管理地点身份时,直接保存文本可能足够。先列出需要回答的查询,再决定地点是否独立建模,可以避免为了绿色类别而建立空壳对象。分类理由应写在模型约定中,今后查询改变时才能重新评估。
这种反例没有证明任意共享描述都必须成为独立对象。如果系统只管理一台设备且说明从不复用,内嵌字段可能更直接。采用独立描述对象的理由,应当来自共享、修订或查询需求,不能只因为类图需要凑齐蓝色节点。
把角色当个人种类会丢掉什么
固定场景中,P1 从 10 点到 20 点是 O1 的租赁经办,从 10 点到 22 点又是 O1 的验收人。两个角色具有不同编号,却关联同一个参与方。查询 12 点能得到两项职责;把经办任职终止于 15 点后,只剩验收角色有效。
错误候选只保存“参与方编号到角色名称”的单值映射。先写经办,再写验收,P1 的值只剩验收。它并没有发现两种职责冲突,只是覆盖了前一项。因此实验同时保留正确的多角色查询与错误候选的覆盖结果,说明分类差异怎样进入运行行为。
任职结束也不删除已存在的租赁约定。A1 保存签订时引用的设备和角色记录,终止当前任职后,仍能取得原参与方 P1 与设备 E1。新约定则必须在开始时点取得有效经办角色。这个检查沿用半开区间,15 点终止意味着 15 点已失效。
这只是教学资格规则,尚未实现认证与授权;它也没有要求任职覆盖整个租期。现实业务若允许任职结束后继续履行旧合同,需要专门确定继任、取消和交接规则。黄色节点没有自动给出这些政策。
蓝色描述也可能有身份和修订
出版社文档组件同时给蓝色模板和绿色文档安排了版本关系。因此,蓝色不能直接推导为“没有身份且永远不变的值对象”。原章中的这个例子可用于检查自动映射的边界。出版社原章,§5.3.1,印刷页177
本章让 CAM-A 发布第二版描述,标签变成修订后的名称。两个修订共享逻辑型号编号,完整记录却不相等。旧约定固定引用第一版;直接按型号编号读取最新版,则会把第二版标签展示到旧约定中。选择哪种展示方式取决于历史需求,本例明确选择签订时的描述。
flowchart TB
V1["CAM-A / 修订1:原说明"] --> OLD["A1:保留签订时描述"]
V2["CAM-A / 修订2:新说明"] --> NEW["当前目录:新说明"]
BAD["错误替代:旧约定只查最新版"] --> V2
classDef blue fill:#c9e2ff,stroke:#355b80,color:#222;
classDef pink fill:#f8c8dc,stroke:#71334b,color:#222;
class V1,V2 blue;
class OLD pink;
第二张图比较版本引用策略,虚构样本只改变标签,不表示实物升级。实验的冻结数据记录是实现手段,蓝色只是分类判断。冻结一份修订有助于避免普通字段覆盖,仍然不等于数据库审计不可篡改,也不自动决定逻辑描述是否具有持续身份。
实现时也无需给四种颜色各建一棵继承树。当前代码直接使用几个小型数据记录,让校验发生在约定构造与角色操作中。颜色只放进夹具说明;删除说明文字不会改变实验结果。这样可以区分维护模型知识的成本与支撑运行行为的代码,避免一个通用 archetype 父类承担没有业务意义的方法。
“合同”这个词还需要细分。本章 A1 表达双方的一次租赁约定,选择粉色;生成的合同文件则可以作为被保存和修订的文档来讨论。一次签署行为、约定关系和 PDF 文件不会因为都被口头叫作合同,就必须具有相同分类。这里尚未实现法律签署或文件生成。
执行与边界
从仓库根目录运行:
1 | |
实验只依赖 Python 3.10 以上标准库和本章 JSON 夹具。本次运行包含 14 个行为场景:实物身份保留、按描述去重的丢失结果、多角色与终止历史、旧约定引用、描述修订,以及过期角色和空期间拒绝。每项输出实际结果或捕获到的业务异常,失败会以非零退出码结束。
夹具中的颜色字符串仅记录建模决定,不作为业务正确性的证据。代码没有自动识别 archetype,也没有给每种颜色建立通用父类。身份索引与版本引用的结果来自对象操作;判断某个业务概念应归哪类,仍需要先确定它要解释的场景。
四种颜色同样不划定聚合。A1 与 E1 存在关联,不足以决定库存检查与约定更新是否必须一起提交。当前实验未处理并发、持久化、重复请求或设备占用,Java RentalDesk 保持原有能力。一次分类实验通过,不能被写成预留系统已支持角色和型号管理。






