语言层:名词与动词的全部构件
对象类型、属性、共享属性、值类型、结构体、派生属性、关系、接口、对象集、Action、函数,一张总图,再加名字怎么写。

本课目标
读完这一课,你将能够
- 说出语言层的十一个构件,并分清名词和动词
- 判断一个需求该用值类型、共享属性、结构体、派生属性还是接口
- 按规则写对构件的名字
十一个构件,三组用途
上一课说,孪生是名词加动词。语言层就是写下它们的那套词汇。构件不多,按用途分三组。
描述一类东西
Object Type是一类业务对象,属性是它的特征。值类型、共享属性、结构体、派生属性让属性更准确、更一致。
连接与共性
Link Type连接两个对象类型;Interface描述几个对象类型共有的形状。
查与改
对象集是一组对象;Action 是受控的修改;Function是代码写的逻辑。
一个对象类型不必用到全部构件。示例工厂里的 Product 只要几个基础类型的属性;Customer 才会用到值类型、结构体和位置。
属性周围的四个构件
对象类型只说有哪类东西,细节都在属性上。属性有二十多种基础类型,从文字、整数、小数、日期,到位置、时间序列、向量。属性的类型决定它能怎样被查:日期能比先后,位置能按距离筛,时间序列能取最新的一点。围绕属性,有四个构件各管一件事:
- 值类型:把规则写进类型。约束有
enum、range、length、regex等,写入时校验,改约束就升版本。例如orderStatus只允许draft到cancelled六个取值。 - 共享属性:一个属性定义,多个对象类型共用,含义永远一致。例如
ownerId、createdAt。 - 结构体:把一组固定字段装成一个属性值,例如
Customer.contact由姓名和邮箱组成。结构体不能嵌套,字段只能是标量和 geopoint。 - 派生属性:不存,读时沿关系计算。例如客户的订单总数
orderCount,沿orders计数。最多走 3 跳,不能用于过滤或排序。派生属性不带筛选条件;未关闭订单数要先过滤再聚合,或用 Function。
不要存一列订单总数,再让人或脚本更新。它容易和实际数量不一致。沿关系直接计数可用派生属性;带筛选条件的计数要先过滤再聚合,或用 Function。
关系、接口与动词
Link Type 连接两个对象类型,两端各有名字,例如 SalesOrder.workOrders 和 WorkOrder.order。一对一、一对多用外键,多对多每条链接单独存。Interface 可以继承;实现它的对象类型要把自己的属性映射到接口属性上,类型必须一致。
| 共享属性 | 接口 | |
|---|---|---|
| 管什么 | 一个属性的定义 | 一组属性和关系的形状 |
| 例子 | ownerId:谁负责 | Schedulable:有 dueAt 和 status |
| 用来做什么 | 让同名字段含义一致 | 跨类型统一查询,找出所有快到期的对象 |
动词这一侧,Action 由参数、规则和提交条件组成,规则有六种:新建、修改、新建或修改、删除对象,建立、解除关系。Function是代码写的逻辑,能以对象为输入。对象集把「找哪些对象」写成一句话:筛选、并交差、沿关系走。例如「状态是 running、本周到期的工单」就是一个对象集。
名字怎么写
名字就是 API、SDK 和命令行里用的名字,大小写有固定规则,第一次就写对:
Object Type PascalCase SalesOrder
Property, Link Type ends camelCase promisedDate, workOrders
Value Type, Shared Property, Function camelCase orderStatus, ownerId
Action Type kebab-case hold-work-order
Interface PascalCase Schedulable
还有一条:新建的对象类型只用一个主键属性。名字是所有入口共用的公共语言,hold-work-order 在 API、CLI 和 SDK 里是同一个词,改名会影响所有调用它的应用,所以一开始就要起对。
这张图里的每个构件,后面都有专门的课讲透:第 2 门课讲对象类型和属性,第 3 门课讲关系与接口,第 5 门课讲 Action,第 6 门课讲函数与逻辑。下一节看这些定义在引擎里是怎样跑起来的。
要点
- 语言层有十一个构件:描述一类东西、连接与共性、查与改三组。
- 值类型管取值规则,共享属性管定义一致,结构体管固定字段,派生属性管读时计算。
- 共享属性让一个字段含义一致,接口让不同对象类型能被一起查询。
- Object Type 和 Interface 用 PascalCase;属性、链接端、Value Type、Shared Property 和 Function 用 camelCase;Action 用 kebab-case。
- Function 已可发布和执行;复杂判断不必只交给智能体。
练一练
给示例工厂的需求选构件
下面三个需求,每一个该用哪个构件?写出理由。
Customer.tier 只能是 standard、key、strategic 之一。它该是什么构件?名字怎么写?
产线要显示「未完成的工单数」。先过滤工单再聚合,或用 Function。写出筛选条件和沿着哪条链接查工单。
销售订单、工单、采购订单都有到期日。想一次找出所有快到期的,需要哪个构件?它要有哪些属性?
小测
选一个答案,马上看解析。
Q1客户的「订单总数」应该怎么建?
订单总数可沿 orders 直接计数。派生属性不带筛选条件;未关闭订单数要先过滤再聚合,或用 Function。
Q2销售订单、工单、采购订单都有到期日。想跨类型找出全部快到期的,应该怎么做?
共享属性只保证一个字段含义一致,接口才让不同类型能被当成一组来查询。
Q3给「暂停工单」这个 Action 起名,哪个写法符合规则?
Action 用 kebab-case;Object Type 和 Interface 用 PascalCase;属性、链接端、Value Type、Shared Property 和 Function 用 camelCase。