Vault

让本体面向未来:Palantir 本体治理的四大原则与反模式

cover

摘要

Palantir 架构师 Chad Wallquist 与前向部署工程师 Jonas 坐下来,拆解客户问得最多的问题:本体(ontology)到底是什么?该不该把数据仓库整个塞进本体?系统表要不要照搬?他们的回答是:本体的目标是「按真实世界运作的方式建模」——用业务实际运营时的名词与动词来表达,而不是为了某个报表工具或系统规模而重塑数据。为此,两人基于软件工程理论与大量现场经验,提炼出四套最佳实践模式与对应的反模式。

本文深挖第一套模式「领域驱动设计」(domain-driven design):动手构建之前先分三步——理解领域、设计本体(对象类型、链接与动作)、再把源数据与逻辑映射上去。以「订单数据」表为例,一比一照搬会把客户、产品、技术属性全部塞进一个对象,催生「上帝对象」(god object)与「厨房水槽」(kitchen sink)两大反模式——技术批号、团队特定标记污染对象类型,让业务用户和技术构建者都看不懂。

正确的做法是拆成订单、客户、产品三个对象类型,从源数据中只提取各对象真正需要的属性并厘清关系。本体的力量在于:所有人都从同一个底座出发说话,不再需要来回翻译。

正文

一、本体是什么:建模真实世界,而非数据仓库

Jonas 开门见山地为「本体」定了调:当他说本体时,想的是如何建模真实世界——它实际如何存在,如何用业务实际运营所依托的名词与动词来建模你的业务,「而不是为了某种报表工具能跑、为了某种系统规模而把数据塞进数据仓库的样子」。Palantir 本体的目标就是按真实世界运作的方式建模,这与人们习惯的东西相比显得有些「奇怪」——也正因如此,这是团队每天都会被问到的话题。

Chad 补充道,这次对话要做的不仅是「去神秘化」,还要讲清楚正确的做法以及多年经验里反复出现的反模式。Jonas 确认:这些设计原则与反模式既扎根于软件工程理论,也来自现场实际——什么在真实世界行得通、什么能为业务带来大量价值、什么能让维护本体的团队也受益。这些最佳实践的核心目标是构建一个稳健、面向未来的本体。

二、四大基础模式:领域驱动、拒绝重复、开闭原则与组合

两人总结出四条根本性的最佳实践模式:领域驱动设计(domain driven design)、不要重复自己(don't repeat yourself,DRY)、开闭原则(open-close principle),以及「组合优于深层继承」(composition over deep hierarchies)。

其中第一项——领域驱动设计——是建模的起点。在真正构建任何东西之前,应该按三步走:第一步,思考并理解你正在处理的领域;第二步,设计本体——对象类型(object types)、对象之间的链接(links)以及作用于这些对象的动作(actions);第三步,把源数据与逻辑映射到这个本体上。这一原则的本质是:你建模的是现实,而不是复刻某个其他软件把你推向的东西。

三、订单数据示例:一对照搬如何制造两大反模式

用一个经典例子说明。源系统里可能有一张叫「订单数据」(order data)的表,如果把它一比一映射进本体,里面会挤进大量不同的实体:客户姓名与邮箱、技术属性——比如本例中「CRM 提取时间、CRM 批次 ID」这类完全没有业务价值的字段。这样建模会引入反模式。

第一个是所谓「上帝对象」(god object):对象类型被团队特定的或纯技术性的属性污染——批次 ID 这类标记被搬运进来,而不是人们真正想用这些对象去完成的功能。更糟的是,这个对象类型同时代表了多个不同的实体——订单、客户、产品混在一起。

第二个是「厨房水槽」(kitchen sink)模式:把所有源列一比一映射进对象类型,哪怕根本用不上。后果是:任何在这个对象类型上工作的人——想改点东西、在 Workshop 应用或某个前端里使用它——都会对着这些属性犯迷糊:「我真需要这个吗?这到底是什么意思?」把对象类型保持聚焦、让每个对象类型真正代表一个不同的现实世界实体,无论对业务人员还是技术构建者都容易理解得多。

四、本体是人的语言:消除翻译摩擦,从同一底座出发

Jonas 强调一个关键点:本体是为了「人类实际怎么说话」而存在的,而不是为了「你的开发者怎么建报表」。他希望本体反映的是业务实际如何运营、如何谈论这些术语。但现场经常看到的反面教材是:批次 ID、技术标记、组件这些「怪东西」被搬进对象,而它们往往不是功能本身,也不是人们想用这些对象达成的目标。结果就是持续的摩擦——作为前向部署工程师,他不得不在业务用户之间来回翻译,因为他讲的是另一种语言。

这就是本体的力量所在:当每个人从同一个底座出发、用同一种语言谈论同一件事,翻译的需求消失了。那么「做对了」长什么样?回到订单的例子:与其只有一个「订单数据」,不如从领域出发——既然我在处理订单,我需要订单本身,我关心这笔订单的客户,也关心订单里的产品。于是得到三个不同的对象类型:订单、客户、产品。再从源数据中识别每个对象类型真正需要的属性,以及它们彼此之间如何关联。先把这些一起建模:人们查看这些对象类型、使用链接、看清彼此关系时会更容易理解;更重要的是,未来的工作流也能真正建立在这个清晰的关系结构之上——这正是稳健、面向未来的本体的根基。

觉得有用?分享给一个需要的朋友 🙏