InterfaceType 与 StructType:类型系统高级特性
场景:多种实体都有"地理位置"
Coomia发布于 2025年8月10日17 分钟阅读
分享本文Twitter / X
InterfaceType 与 StructType:类型系统高级特性
“系列:S4 本体建模 · 第 6 篇 | 难度:中级 | 阅读时间:18 分钟
#TL;DR
- InterfaceType 让 Ontology 拥有面向对象的"接口继承"能力——多个 ObjectType 可以实现同一个 Interface,支持多态查询("查所有可定位的对象"而不用关心是设备、仓库还是车辆)。
- StructType 是轻量级的"值对象"——不像 ObjectType 有独立身份和生命周期,Struct 是嵌入在属性中的复合数据结构,支持多层嵌套,适合地址、坐标、联系人信息等场景。
- 接口继承 + 结构体嵌套 + 多态查询三者协同,让 Ontology 的表达力从简单的"表→行→列"跃升到类型安全的领域建模。
#1. 为什么需要 InterfaceType
#1.1 问题:类型之间的共性如何表达?
Code
场景:多种实体都有"地理位置"
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Equipment│ │ Warehouse│ │ Vehicle │ │ Employee │
│ │ │ │ │ │ │ │
│ lat: 31.2│ │ lat: 39.9│ │ lat: 22.3│ │ lat: 30.6│
│ lng: 121 │ │ lng: 116 │ │ lng: 114 │ │ lng: 104 │
│ address │ │ address │ │ address │ │ address │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
问题:
├── 如何查询"距离我 10 公里内的所有可定位对象"?
├── 传统做法:分别查 4 张表 → UNION ALL → 客户端合并
├── 如果新增了 ObjectType(如 Sensor),查询逻辑又要改
└── 没有办法在 Schema 层面表达"这些类型有共同的能力"
解决:InterfaceType
┌──────────────────────────────────┐
│ InterfaceType: Locatable │
│ │
│ properties: │
│ ├── latitude: DOUBLE │
│ ├── longitude: DOUBLE │
│ └── address: STRING │
│ │
│ implementedBy: │
│ ├── Equipment │
│ ├── Warehouse │
│ ├── Vehicle │
│ └── Employee │
└──────────────────────────────────┘
现在可以:
client.objects.search("Locatable", filters={"nearPoint": ...})
→ 自动跨所有实现类查询,返回混合结果
#1.2 InterfaceType vs 传统继承
Code
┌────────────────┬───────────────────────┬─────────────────────┐
│ │ 传统 OOP 继承 │ InterfaceType │
├────────────────┼───────────────────────┼─────────────────────┤
│ 多继承 │ 通常不支持/菱形问题 │ ✅ 一个类型可实现 │
│ │ │ 多个 Interface │
├────────────────┼───────────────────────┼─────────────────────┤
│ 数据存储 │ 通常映射到表继承 │ 各 ObjectType 独立 │
│ │ (STI/MTI) │ 存储,无共享表 │
├────────────────┼───────────────────────┼─────────────────────┤
│ 查询方式 │ 查父类表 │ 多态查询自动聚合 │
│ │ │ 各实现类结果 │
├────────────────┼───────────────────────┼─────────────────────┤
│ 运行时耦合 │ 紧耦合 │ 松耦合 │
│ │ │ Interface 变更不影响│
│ │ │ 实现类存储 │
└────────────────┴───────────────────────┴─────────────────────┘
#2. InterfaceType 数据模型
#2.1 定义 Interface
Python
from ontology_sdk import OntologyClient
client = OntologyClient(base_url="http://localhost:8080")
# 创建 InterfaceType
interface = client.schema.create_interface_type({
"apiName": "Locatable",
"displayName": "可定位",
"description": "表示具有地理位置的实体",
# 接口定义的属性(实现类必须具备)
"properties": {
"latitude": {
"type": "DOUBLE",
"required": True,
"description": "纬度",
"validations": [
{"rule": "min", "value": -90},
{"rule": "max", "value": 90},
],
},
"longitude": {
"type": "DOUBLE",
"required": True,
"description": "经度",
"validations": [
{"rule": "min", "value": -180},
{"rule": "max", "value": 180},
],
},
"address": {
"type": "STRING",
"required": False,
"description": "人类可读地址",
},
},
# 接口定义的方法/操作(可选)
"actions": [
{
"apiName": "updateLocation",
"parameters": {
"newLatitude": {"type": "DOUBLE", "required": True},
"newLongitude": {"type": "DOUBLE", "required": True},
},
},
],
})
#2.2 ObjectType 实现 Interface
Python
# 让 Equipment 实现 Locatable 接口
client.schema.create_object_type({
"name": "Equipment",
"primaryKey": "equipmentId",
# 声明实现的接口列表
"implements": ["Locatable", "Auditable", "Maintainable"],
"properties": {
"equipmentId": {"type": "STRING", "required": True},
"name": {"type": "STRING", "required": True},
"model": {"type": "STRING"},
# Locatable 接口要求的属性
"latitude": {"type": "DOUBLE", "required": True},
"longitude": {"type": "DOUBLE", "required": True},
"address": {"type": "STRING"},
# Auditable 接口要求的属性
"createdAt": {"type": "TIMESTAMP", "required": True},
"updatedAt": {"type": "TIMESTAMP", "required": True},
"createdBy": {"type": "STRING", "required": True},
# Maintainable 接口要求的属性
"lastMaintenanceDate": {"type": "DATE"},
"nextMaintenanceDate": {"type": "DATE"},
"maintenanceStatus": {"type": "ENUM", "enumValues": ["NORMAL", "DUE", "OVERDUE"]},
# Equipment 自己的属性
"serialNumber": {"type": "STRING"},
"purchaseDate": {"type": "DATE"},
"warrantyExpiry": {"type": "DATE"},
},
})
#2.3 接口合规性检查
Python
# 系统自动验证 ObjectType 是否满足 Interface 的所有要求
try:
client.schema.create_object_type({
"name": "Sensor",
"primaryKey": "sensorId",
"implements": ["Locatable"],
"properties": {
"sensorId": {"type": "STRING", "required": True},
"latitude": {"type": "DOUBLE", "required": True},
# 缺少 longitude!
},
})
except InterfaceComplianceError as e:
print(f"接口合规性检查失败: {e}")
# "ObjectType 'Sensor' does not satisfy interface 'Locatable':
# Missing required property: longitude (DOUBLE)"
print(f"缺失属性: {e.missing_properties}")
print(f"类型不匹配: {e.type_mismatches}")
#3. 多态查询
#3.1 基于 Interface 的跨类型查询
Python
# 查询所有实现了 Locatable 接口的对象
# 无需知道具体有哪些 ObjectType
results = client.objects.search_by_interface("Locatable", {
"filters": {
"nearPoint": {
"latitude": 31.23,
"longitude": 121.47,
"radiusKm": 10,
},
},
"orderBy": "distance",
"maxResults": 50,
})
for obj in results:
print(f"[{obj.object_type}] {obj.display_name}")
print(f" 位置: ({obj.latitude}, {obj.longitude})")
print(f" 距离: {obj.distance_km:.1f} km")
# 输出示例:
# [Equipment] CNC-001 数控机床
# 位置: (31.24, 121.48)
# 距离: 1.2 km
# [Warehouse] 浦东仓库
# 位置: (31.22, 121.50)
# 距离: 2.8 km
# [Vehicle] 沪A-12345 运输车
# 位置: (31.20, 121.45)
# 距离: 3.5 km
#3.2 多态查询的执行原理
Code
多态查询执行流程:
1. 解析 Interface
┌─────────────────┐
│ Locatable │
│ ├── Equipment │
│ ├── Warehouse │
│ ├── Vehicle │
│ └── Employee │
└─────────────────┘
2. 并行查询各实现类(Fan-out)
┌─────────────┐
│ Equipment │──── Query with filters ──── Results[0..n]
│ Warehouse │──── Query with filters ──── Results[0..m]
│ Vehicle │──── Query with filters ──── Results[0..k]
│ Employee │──── Query with filters ──── Results[0..j]
└─────────────┘
3. 合并排序(Fan-in)
Results[0..n] ─┐
Results[0..m] ─┼── Merge Sort by distance ── Final Results
Results[0..k] ─┤
Results[0..j] ─┘
性能特征:
├── 并行度 = 实现类数量(通常 3-10 个)
├── 响应时间 ≈ 最慢的实现类查询时间
├── 结果数量 = 各实现类结果之和(受 maxResults 限制)
└── 自动优化:如果某实现类不可能满足过滤条件,跳过查询
#3.3 Interface 继承
Python
# InterfaceType 也可以继承其他 InterfaceType
client.schema.create_interface_type({
"apiName": "TrackableAsset",
"displayName": "可追踪资产",
# 继承 Locatable(拥有位置属性)
"extends": ["Locatable"],
# 额外的属性
"properties": {
"assetTag": {
"type": "STRING",
"required": True,
"description": "资产标签编号",
},
"assetValue": {
"type": "DOUBLE",
"required": True,
"description": "资产价值(元)",
},
"depreciationRate": {
"type": "DOUBLE",
"description": "年折旧率",
},
},
})
# Equipment 同时满足 Locatable 和 TrackableAsset
# 查询 TrackableAsset 时也能找到 Equipment
#4. StructType:值对象建模
#4.1 为什么需要 StructType
Code
场景:地址信息的建模
方案 A:扁平属性(Bad)
┌─────────────────────────────────┐
│ Employee │
│ ├── homeCountry: STRING │
│ ├── homeProvince: STRING │
│ ├── homeCity: STRING │
│ ├── homeStreet: STRING │
│ ├── homePostcode: STRING │
│ ├── workCountry: STRING │ ← 属性爆炸!
│ ├── workProvince: STRING │
│ ├── workCity: STRING │
│ ├── workStreet: STRING │
│ └── workPostcode: STRING │
└─────────────────────────────────┘
方案 B:独立 ObjectType(Overkill)
┌──────────┐ 1:N ┌──────────┐
│ Employee │──────►│ Address │
└──────────┘ └──────────┘
├── 地址需要独立 ID?不需要
├── 地址需要独立生命周期?不需要
├── 地址需要被其他对象引用?不需要
└── 多余的关系管理开销
方案 C:StructType(Just Right)
┌─────────────────────────────────┐
│ Employee │
│ ├── homeAddress: Address │ ← 嵌入式复合结构
│ └── workAddress: Address │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ StructType: Address │
│ ├── country: STRING │
│ ├── province: STRING │
│ ├── city: STRING │
│ ├── street: STRING │
│ └── postcode: STRING │
└─────────────────────────────────┘
#4.2 定义 StructType
Python
# 创建 StructType
client.schema.create_struct_type({
"apiName": "Address",
"displayName": "地址",
"description": "表示一个邮寄地址",
"properties": {
"country": {
"type": "STRING",
"required": True,
"defaultValue": "中国",
},
"province": {"type": "STRING", "required": True},
"city": {"type": "STRING", "required": True},
"district": {"type": "STRING"},
"street": {"type": "STRING", "required": True},
"postcode": {
"type": "STRING",
"validations": [
{"rule": "pattern", "value": "^[0-9]{6}$", "message": "邮编必须为 6 位数字"},
],
},
"isDefault": {"type": "BOOLEAN", "defaultValue": "false"},
},
})
# 创建 GeoPoint StructType
client.schema.create_struct_type({
"apiName": "GeoPoint",
"displayName": "地理坐标",
"properties": {
"latitude": {
"type": "DOUBLE",
"required": True,
"validations": [
{"rule": "min", "value": -90},
{"rule": "max", "value": 90},
],
},
"longitude": {
"type": "DOUBLE",
"required": True,
"validations": [
{"rule": "min", "value": -180},
{"rule": "max", "value": 180},
],
},
"altitude": {"type": "DOUBLE", "description": "海拔(米)"},
"accuracy": {"type": "DOUBLE", "description": "精度(米)"},
},
})
#4.3 在 ObjectType 中使用 StructType
Python
# 在 ObjectType 属性中引用 StructType
client.schema.create_object_type({
"name": "Employee",
"primaryKey": "employeeId",
"properties": {
"employeeId": {"type": "STRING", "required": True},
"name": {"type": "STRING", "required": True},
# 使用 StructType 作为属性类型
"homeAddress": {
"type": "STRUCT",
"structType": "Address",
"required": True,
},
"workAddress": {
"type": "STRUCT",
"structType": "Address",
},
# StructType 数组
"emergencyContacts": {
"type": "ARRAY",
"itemType": "STRUCT",
"structType": "ContactInfo",
"maxItems": 3,
},
},
})
# 创建对象时直接嵌入 Struct 值
employee = client.objects.create("Employee", {
"employeeId": "emp-001",
"name": "张三",
"homeAddress": {
"country": "中国",
"province": "上海市",
"city": "上海市",
"district": "浦东新区",
"street": "张江高科技园区碧波路 100 号",
"postcode": "201203",
"isDefault": True,
},
"workAddress": {
"country": "中国",
"province": "上海市",
"city": "上海市",
"street": "陆家嘴环路 1000 号",
"postcode": "200120",
},
"emergencyContacts": [
{"name": "李四", "phone": "13800138001", "relationship": "配偶"},
{"name": "王五", "phone": "13800138002", "relationship": "父母"},
],
})
#4.4 嵌套查询
Python
# 查询嵌套 Struct 中的字段
results = client.objects.search("Employee", {
"filters": {
"homeAddress.city": {"eq": "上海市"},
"homeAddress.district": {"eq": "浦东新区"},
},
})
# 查询 Struct 数组中的字段
results = client.objects.search("Employee", {
"filters": {
"emergencyContacts.relationship": {"eq": "配偶"},
},
})
#5. Struct 嵌套:多层复合结构
#5.1 多层嵌套定义
Python
# 三层嵌套示例:订单 → 行项目 → 价格明细
# 第一层:PriceBreakdown
client.schema.create_struct_type({
"apiName": "PriceBreakdown",
"properties": {
"basePrice": {"type": "DOUBLE", "required": True},
"discount": {"type": "DOUBLE", "defaultValue": "0"},
"discountReason": {"type": "STRING"},
"tax": {"type": "DOUBLE", "required": True},
"taxRate": {"type": "DOUBLE", "required": True},
"finalPrice": {"type": "DOUBLE", "required": True},
},
})
# 第二层:OrderLineItem(包含 PriceBreakdown)
client.schema.create_struct_type({
"apiName": "OrderLineItem",
"properties": {
"productId": {"type": "STRING", "required": True},
"productName": {"type": "STRING", "required": True},
"quantity": {"type": "INTEGER", "required": True, "validations": [{"rule": "min", "value": 1}]},
"unit": {"type": "STRING", "defaultValue": "件"},
"pricing": {
"type": "STRUCT",
"structType": "PriceBreakdown", # 嵌套引用
"required": True,
},
"notes": {"type": "STRING"},
},
})
# 第三层:在 Order ObjectType 中使用
client.schema.create_object_type({
"name": "Order",
"primaryKey": "orderId",
"properties": {
"orderId": {"type": "STRING", "required": True},
"customerId": {"type": "STRING", "required": True},
"lineItems": {
"type": "ARRAY",
"itemType": "STRUCT",
"structType": "OrderLineItem",
"minItems": 1,
"maxItems": 100,
},
"shippingAddress": {
"type": "STRUCT",
"structType": "Address",
},
"totalAmount": {"type": "DOUBLE"},
},
})
#5.2 嵌套限制与最佳实践
Code
嵌套深度限制:
coomia-dip 支持最多 5 层嵌套:
ObjectType
└── Struct Level 1
└── Struct Level 2
└── Struct Level 3
└── Struct Level 4
└── Struct Level 5 (最大深度)
超过 5 层时的替代方案:
├── 拆分为独立的 ObjectType + RelationType
├── 重新审视数据模型是否过于复杂
└── 考虑使用 JSON 类型存储半结构化数据
最佳实践:
├── 嵌套深度控制在 2-3 层
├── Struct 属性不超过 15 个字段
├── Struct 数组不超过 50 个元素
├── 对频繁查询的嵌套字段建立索引
└── 避免在 Struct 中放大文本字段(影响存储效率)
#6. InterfaceType + StructType 组合使用
Python
# 组合示例:可监控设备
# StructType:传感器读数
client.schema.create_struct_type({
"apiName": "SensorReading",
"properties": {
"sensorId": {"type": "STRING", "required": True},
"value": {"type": "DOUBLE", "required": True},
"unit": {"type": "STRING", "required": True},
"timestamp": {"type": "TIMESTAMP", "required": True},
"quality": {"type": "ENUM", "enumValues": ["GOOD", "UNCERTAIN", "BAD"]},
},
})
# InterfaceType:可监控
client.schema.create_interface_type({
"apiName": "Monitorable",
"displayName": "可监控",
"properties": {
"healthStatus": {
"type": "ENUM",
"enumValues": ["HEALTHY", "WARNING", "CRITICAL", "UNKNOWN"],
"required": True,
},
"lastHeartbeat": {"type": "TIMESTAMP", "required": True},
"currentReadings": {
"type": "ARRAY",
"itemType": "STRUCT",
"structType": "SensorReading",
},
},
"actions": [
{"apiName": "resetHealth", "parameters": {}},
{"apiName": "acknowledgeAlert", "parameters": {
"alertId": {"type": "STRING", "required": True},
}},
],
})
# ObjectType 同时使用 InterfaceType 和 StructType
client.schema.create_object_type({
"name": "IndustrialRobot",
"primaryKey": "robotId",
"implements": ["Locatable", "Monitorable", "TrackableAsset"],
"properties": {
"robotId": {"type": "STRING", "required": True},
"name": {"type": "STRING", "required": True},
"model": {"type": "STRING"},
"manufacturer": {"type": "STRING"},
# 来自 Locatable
"latitude": {"type": "DOUBLE", "required": True},
"longitude": {"type": "DOUBLE", "required": True},
"address": {"type": "STRING"},
# 来自 Monitorable
"healthStatus": {"type": "ENUM", "enumValues": ["HEALTHY", "WARNING", "CRITICAL", "UNKNOWN"], "required": True},
"lastHeartbeat": {"type": "TIMESTAMP", "required": True},
"currentReadings": {
"type": "ARRAY",
"itemType": "STRUCT",
"structType": "SensorReading",
},
# 来自 TrackableAsset
"assetTag": {"type": "STRING", "required": True},
"assetValue": {"type": "DOUBLE", "required": True},
"depreciationRate": {"type": "DOUBLE"},
# 自有属性
"operatingHours": {"type": "DOUBLE"},
"jointConfiguration": {
"type": "STRUCT",
"structType": "RobotJointConfig",
},
},
})
#7. 类型系统对比:何时用什么
Code
┌─────────────────┬────────────────┬────────────────┬───────────────┐
│ 特征 │ ObjectType │ InterfaceType │ StructType │
├─────────────────┼────────────────┼────────────────┼───────────────┤
│ 有独立身份(PK) │ ✅ 有 │ ❌ 无 │ ❌ 无 │
│ 可独立存在 │ ✅ 是 │ ❌ 否 │ ❌ 否 │
│ 可被引用(关系) │ ✅ 可以 │ ❌ 不可以 │ ❌ 不可以 │
│ 有生命周期 │ ✅ DRAFT→... │ ✅ DRAFT→... │ ✅ DRAFT→... │
│ 可独立查询 │ ✅ 可以 │ ✅ 多态查询 │ ❌ 不可以 │
│ 可嵌套 │ ❌ 不可以 │ ❌ 不可以 │ ✅ 可以 │
│ 存储方式 │ 独立表/分区 │ 无存储 │ 嵌入宿主对象 │
│ 典型用途 │ 业务实体 │ 共性抽象 │ 值对象 │
└─────────────────┴────────────────┴────────────────┴───────────────┘
决策树:
需要建模一个概念?
│
├── 它有独立身份和生命周期?
│ ├── Yes → ObjectType
│ └── No → 它代表多个类型的共性?
│ ├── Yes → InterfaceType
│ └── No → 它是一个复合值?
│ ├── Yes → StructType
│ └── No → 简单属性(STRING/DOUBLE/...)
#8. Protobuf 定义
PROTOBUF
message InterfaceType {
string api_name = 1;
string display_name = 2;
string description = 3;
// 继承的父接口
repeated string extends = 4;
// 接口定义的属性
map<string, PropertyDef> properties = 5;
// 接口定义的操作
repeated ActionSignature actions = 6;
// 实现此接口的 ObjectType 列表(自动维护)
repeated string implemented_by = 7;
LifecycleState lifecycle = 8;
}
message StructType {
string api_name = 1;
string display_name = 2;
string description = 3;
// 结构体字段
map<string, PropertyDef> properties = 4;
// 被哪些类型引用(自动维护)
repeated StructUsage usages = 5;
LifecycleState lifecycle = 6;
}
message StructUsage {
string object_type = 1;
string property_name = 2;
bool is_array = 3;
}
#9. 实战案例:智能工厂类型体系
Python
# 完整的智能工厂类型系统设计
# === StructTypes ===
# 维护记录
client.schema.create_struct_type({
"apiName": "MaintenanceRecord",
"properties": {
"date": {"type": "DATE", "required": True},
"technician": {"type": "STRING", "required": True},
"type": {"type": "ENUM", "enumValues": ["PREVENTIVE", "CORRECTIVE", "PREDICTIVE"]},
"description": {"type": "STRING", "required": True},
"duration_hours": {"type": "DOUBLE"},
"cost": {"type": "DOUBLE"},
"parts_replaced": {"type": "ARRAY", "itemType": "STRING"},
},
})
# 告警规则
client.schema.create_struct_type({
"apiName": "AlertRule",
"properties": {
"metric": {"type": "STRING", "required": True},
"operator": {"type": "ENUM", "enumValues": ["GT", "LT", "EQ", "GTE", "LTE"]},
"threshold": {"type": "DOUBLE", "required": True},
"severity": {"type": "ENUM", "enumValues": ["INFO", "WARNING", "CRITICAL"]},
"cooldownMinutes": {"type": "INTEGER", "defaultValue": "15"},
},
})
# === InterfaceTypes ===
# 可审计
client.schema.create_interface_type({
"apiName": "Auditable",
"properties": {
"createdAt": {"type": "TIMESTAMP", "required": True},
"updatedAt": {"type": "TIMESTAMP", "required": True},
"createdBy": {"type": "STRING", "required": True},
"updatedBy": {"type": "STRING"},
},
})
# 可维护
client.schema.create_interface_type({
"apiName": "Maintainable",
"extends": ["Auditable"],
"properties": {
"lastMaintenanceDate": {"type": "DATE"},
"nextMaintenanceDate": {"type": "DATE"},
"maintenanceHistory": {
"type": "ARRAY",
"itemType": "STRUCT",
"structType": "MaintenanceRecord",
},
"alertRules": {
"type": "ARRAY",
"itemType": "STRUCT",
"structType": "AlertRule",
},
},
"actions": [
{"apiName": "scheduleMaintenance", "parameters": {
"date": {"type": "DATE", "required": True},
"type": {"type": "STRING", "required": True},
}},
],
})
# === ObjectTypes ===
# CNC 机床
client.schema.create_object_type({
"name": "CNCMachine",
"primaryKey": "machineId",
"implements": ["Locatable", "Monitorable", "Maintainable", "TrackableAsset"],
"properties": {
"machineId": {"type": "STRING", "required": True},
"name": {"type": "STRING", "required": True},
# ... Locatable 属性
"latitude": {"type": "DOUBLE", "required": True},
"longitude": {"type": "DOUBLE", "required": True},
"address": {"type": "STRING"},
# ... Monitorable 属性
"healthStatus": {"type": "ENUM", "enumValues": ["HEALTHY", "WARNING", "CRITICAL", "UNKNOWN"], "required": True},
"lastHeartbeat": {"type": "TIMESTAMP", "required": True},
"currentReadings": {"type": "ARRAY", "itemType": "STRUCT", "structType": "SensorReading"},
# ... Maintainable 属性
"createdAt": {"type": "TIMESTAMP", "required": True},
"updatedAt": {"type": "TIMESTAMP", "required": True},
"createdBy": {"type": "STRING", "required": True},
"updatedBy": {"type": "STRING"},
"lastMaintenanceDate": {"type": "DATE"},
"nextMaintenanceDate": {"type": "DATE"},
"maintenanceHistory": {"type": "ARRAY", "itemType": "STRUCT", "structType": "MaintenanceRecord"},
"alertRules": {"type": "ARRAY", "itemType": "STRUCT", "structType": "AlertRule"},
# ... TrackableAsset 属性
"assetTag": {"type": "STRING", "required": True},
"assetValue": {"type": "DOUBLE", "required": True},
"depreciationRate": {"type": "DOUBLE"},
# CNC 专有属性
"spindleSpeed": {"type": "INTEGER", "description": "主轴转速 RPM"},
"axisCount": {"type": "INTEGER", "description": "轴数(3/4/5)"},
"maxWorkpieceSize": {"type": "STRUCT", "structType": "Dimensions3D"},
},
})
# 多态查询示例
print("=== 所有需要维护的设备 ===")
overdue = client.objects.search_by_interface("Maintainable", {
"filters": {
"nextMaintenanceDate": {"lt": "2026-03-24"},
"healthStatus": {"in": ["WARNING", "CRITICAL"]},
},
"orderBy": "nextMaintenanceDate",
})
for item in overdue:
print(f"[{item.object_type}] {item.name}")
print(f" 下次维护: {item.nextMaintenanceDate}")
print(f" 健康状态: {item.healthStatus}")
print(f" 维护历史: {len(item.maintenanceHistory)} 条记录")
#10. 版本演进与兼容性
Python
# InterfaceType 的版本演进
# 安全变更(向后兼容):
# ✅ 添加可选属性
# ✅ 添加新的 Action
# ✅ 放宽验证规则(如增大 max 值)
# 破坏性变更(需要走 Schema Change 流程):
# ❌ 删除已有属性
# ❌ 添加必填属性(已有实现类可能不满足)
# ❌ 修改属性类型
# ❌ 收紧验证规则
# StructType 的版本演进同理
# 额外注意:StructType 被多个 ObjectType 引用时,变更影响面更大
#Key Takeaways
- InterfaceType 实现了 Ontology 级别的多态——一次查询跨多个 ObjectType,无需硬编码类型列表,新增实现类自动纳入查询范围。
- StructType 是属性级别的复合类型——避免了属性爆炸(扁平化)和过度建模(独立 ObjectType),支持最多 5 层嵌套。
- 一个 ObjectType 可以实现多个 Interface——类似多重继承但无菱形问题,各 Interface 的属性独立,不存在冲突。
- 类型系统三要素协同:ObjectType(业务实体) + InterfaceType(共性抽象) + StructType(值对象) = 完整的领域建模能力。
- 接口合规性自动检查——创建或修改 ObjectType 时,系统验证是否满足所有声明的 Interface 要求。
#Next Article
下一篇 S4-07 派生属性 将介绍如何让数据"自己算出来"——通过 9 种 Reducer、表达式求值和 SQL 支撑的派生属性机制,实现"定义一次,自动更新"。
#ontology #interface-type #struct-type #polymorphic-query #type-system #inheritance #value-object