语言层:名词与动词的全部构件

第 2 课 · 共 6 课 约 8 分钟

对象类型、属性、共享属性、值类型、结构体、派生属性、关系、接口、对象集、Action、函数,一张总图,再加名字怎么写。

本课目标

读完这一课,你将能够

  • 说出语言层的十一个构件,并分清名词和动词
  • 判断一个需求该用值类型、共享属性、结构体、派生属性还是接口
  • 按规则写对构件的名字

十一个构件,三组用途

上一课说,孪生是名词加动词。语言层就是写下它们的那套词汇。构件不多,按用途分三组。

DESCRIBE

描述一类东西

Object Type是一类业务对象,属性是它的特征。值类型、共享属性、结构体、派生属性让属性更准确、更一致。

CONNECT

连接与共性

Link Type连接两个对象类型;Interface描述几个对象类型共有的形状。

ACT

查与改

对象集是一组对象;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 之一。它该是什么构件?名字怎么写?

小测

选一个答案,马上看解析。

Q1客户的「订单总数」应该怎么建?

Q2销售订单、工单、采购订单都有到期日。想跨类型找出全部快到期的,应该怎么做?

Q3给「暂停工单」这个 Action 起名,哪个写法符合规则?

延伸阅读