十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Teable v2 字段领域模型架构解析:Field 基类、工厂、Spec 与 Visitor 的协作设计

Teable v2 字段领域模型架构解析:Field 基类、工厂、Spec 与 Visitor 的协作设计 Teable v2 字段领域模型架构解析Field 基类、工厂、Spec 与 Visitor 的协作设计【免费下载链接】teable✨ AI Spreadsheet for Business项目地址: https://gitcode.com/GitHub_Trending/te/teableTeable 的 v2 领域内核packages/v2/core把表格建模能力收敛到domain/table/fields模块本文以 fields/ARCHITECTURE.md 为骨架结合其源码实现系统拆解字段实体基类、22 种字段子类型、字段工厂、Spec 规范构建器与 Visitor 访问者体系的分层设计帮助你在 Teable 上做二次开发或领域建模时快速定位字段从创建、校验到跨表联动的完整链路。一、模块定位fields 目录在领域层中的职责边界根据 fields/ARCHITECTURE.md 的 Responsibilities 声明该目录承担三件核心职责字段实体基类、字段类型与字段工厂定义所有字段共享的行为骨架并提供统一入口创建任意字段子类型共享字段抽象与重水合rehydrated值对象从持久化数据还原出带校验能力的值对象例如DbFieldName系统字段与计算字段created time/by、last modified time/by、auto number 这类由系统自动维护、不可手工编辑的字段。从代码结构看Field是抽象基类Field.ts继承自领域层通用实体基类EntityFieldId即每个字段实例都以FieldId作为实体标识而FieldFactory.ts则是面向外部的唯一构造入口两者共同构成基类约束 工厂分发的建模骨架。二、目录结构总览三个子文件夹与根文件的分工模块采用根文件 三个子包的扁平布局位置内容职责specs/字段规范与构建器以规格Specification模式表达字段满足哪些条件types/字段子类型与类型专属值对象每种字段一个实体类外加计算/非空/唯一等标志值对象visitors/字段访问者接口与默认实现以 Visitor 模式实现按字段类型分派逻辑根目录Field.ts、FieldFactory.ts、FieldId.ts等基类、工厂、通用值对象与工具函数根目录文件按职责可分为四组实体基类Field.ts —— 共享行为与访问者入口构造入口FieldFactory.ts —— 创建字段子类型通用值对象FieldId.ts、FieldName.ts、FieldType.ts、DbFieldName.ts —— 校验与包装跨表与工具ForeignTableRelatedField.ts、fieldPredicates.ts以及位于visitors/下的跨表副作用访问者。三、Field 基类共享行为与访问者入口Field.ts 是全部字段子类型的抽象基类构造函数集中管理以下核心状态id实体标识类型为FieldIdnameValue/typeValue字段名与字段类型均以不可变值对象保存dbFieldNameValue/dbFieldTypeValue持久化层字段名与字段类型默认初始化为空DbFieldName.empty()/DbFieldType.empty()由仓储层在重水合时通过setDbFieldName/setDbFieldType写入dependenciesValue/dependentsValue字段依赖关系dependencies指本字段计算所依赖的其他字段如公式字段引用dependents指反向依赖本字段的字段列表computedValue计算字段标志默认FieldComputed.manual()notNullValue/uniqueValue非空与唯一约束标志默认分别为optional与disabled。基类通过一组约束联动规则保证领域不变量当字段为计算字段computed()为真时notNull()强制返回optionalunique()强制返回disabled且setNotNull/setUnique会直接拒绝为计算字段开启非空或唯一分别返回validation与conflict域错误从 Field.ts 的实现可见这一约束在赋值入口即被拦截setDbFieldName一旦设置后不允许二次改写返回DbFieldName already set不变量错误而renameDbFieldName则要求必须先已设置二者构成只能改一次、必须先存在的写入纪律依赖数组通过setDependencies/setDependents维护使用hasSameFieldIds做内容级比较避免无意义更新。基类还定义了两个抽象方法构成所有子类型的扩展点abstract acceptT void(visitor: IFieldVisitorT): ResultT, DomainError; abstract duplicate(params: FieldDuplicateParams): ResultField, DomainError;accept是访问者模式的入口任何针对具体字段类型的逻辑值类型推导、表单可见性、创建/删除副作用等都通过传入IFieldVisitor实现基类无需感知子类型差异。duplicate用于字段复制其实现约定见 Field.ts 的注释为新字段使用新FieldId与新名称且不复制dbFieldName/dbFieldType同时不得改动表的主字段主字段切换由表层级处理。withName方法则直接委托给duplicate供复制场景复用。此外基类提供spec()入口返回 FieldConditionSpecBuilder用于记录过滤条件以及isMultipleCellValue()通过 FieldValueTypeVisitor 判断单元格值是否为多值如多选、多用户、链接数组。四、值对象层FieldId / FieldName / FieldType / DbFieldName值对象统一继承ValueObject以create(raw)静态方法 zod 校验 Result返回值的方式提供构造即校验能力。FieldIdFieldId.ts的规则最值得关注前缀固定为fld主体长度为 16 位fieldIdBodyLength 16同时兼容最长 64 位的旧版 IDlegacyFieldIdMaxBodyLength 64并允许_数字后缀正则表达式为^fld[0-9a-zA-Z]{1,64}(?:_\d)?$generate()通过generatePrefixedId生成失败时返回unexpected域错误mustGenerate()则在极端失败场景下用随机回退体兜底保证 ID 必然可用提供equals与toString方便在集合与字符串间互转。FieldNameFieldName.ts规则简单直接trim后非空字符串z.string().trim().min(1)空串与纯空白都会被判为Invalid FieldName。FieldTypeFieldType.ts以z.enum定义完整的 22 种字段类型字面量singleLineText, longText, number, rating, formula, rollup, lookup, singleSelect, multipleSelect, checkbox, attachment, date, createdTime, lastModifiedTime, user, createdBy, lastModifiedBy, autoNumber, button, link, conditionalRollup, conditionalLookup每个类型都提供静态工厂方法如FieldType.number()并通过isPrimarySupported()暴露主字段候选类型集合singleLineText、longText、user、multipleSelect、singleSelect、date、number、rating、formula、createdTime、lastModifiedTime、createdBy、lastModifiedBy、autoNumber—— 即只有这 14 类可被设为主字段。DbFieldName作为重水合值对象在实体从数据库还原后被写入由setDbFieldName调用其value()校验用于桥接领域字段名与物理列名。五、FieldFactory22 种字段的统一创建入口FieldFactory.ts 是模块面向业务层的门面为每种字段导出一个create*Field函数。所有函数遵循同一模式调用子类型自身的create/createPending静态方法构造实体通过applyFieldValidation链式应用可选的notNull/unique标志FieldFactory.ts全程以ResultField, DomainError返回错误通过andThen短路传播。工厂函数按类别可归纳为类别工厂函数关键参数文本createSingleLineTextField/createTextField/createLongTextFieldshowAs、defaultValue数值createNumberField、createRatingFieldformatting、showAs、defaultValuerating 另有max/icon/color计算createFormulaField、createRollupField、createConditionalRollupFieldexpression、valuesField、timeZone、dependencies选择createSelectField/createSingleSelectField、createMultipleSelectFieldoptions、preventAutoNewOptions布尔/附件/日期createCheckboxField、createAttachmentField、createDateFielddefaultValue、formatting系统字段createCreatedTimeField、createLastModifiedTimeField、createCreatedByField、createLastModifiedByField、createAutoNumberFieldmetaGeneratedColumnMeta、trackedFieldIds用户/链接/按钮createUserField、createLinkField、createNewLinkField、createButtonFieldisMultiple、config、workflow、confirm待定计算createRollupFieldPending、createLookupFieldPending、createConditionalRollupFieldPending、createConditionalLookupFieldPending用于先建字段、后补结果类型/元数据的异步场景其中两个细节值得注意createNewLinkField是链接字段的新建入口额外接收baseId、hostTableId与宿主/外部表的物理表名DbTableName用于跨表引用初始化Pending系列工厂面向先落字段、再异步推导结果类型的创建流程例如createLookupFieldPending通过innerOptionsPatch与legacyMultiplicityDerivation兼容不同版本的多值推导逻辑。工厂的完整测试覆盖见 FieldFactory.spec.ts其按创建分支逐类断言是理解每种字段参数约定的最佳阅读起点。六、specs 子模块用规格模式描述字段specs/目录实现字段规格Field Specification用于以组合式断言表达某字段是否满足某类条件其用途覆盖查询、过滤、校验等多个场景。架构说明见 specs/ARCHITECTURE.md。核心是构建器 FieldSpecBuilder.ts它继承通用SpecBuilderField, ISpecVisitor, FieldSpecBuilder支持and/or两种组合模式并提供链式 API标识匹配withFieldId、withFieldName、withField按 key 匹配、isPrimary(primaryFieldId)类型匹配isLink、isFormula、isRollup、isLookup、isComputed、isSingleText、isLongText、isNumber、isRating、isNumberFieldnumber/rating、isNumberLike按值类型、isSingleSelect、isMultipleSelect、isCheckbox、isAttachment、isDate、isDateLike、isButton、isUser单元格值类型匹配isNumberValue、isDateTimeValue、isStringValue、isBooleanValue、isJson组合操作andGroup、orGroup、not最后通过build()产出ResultISpecificationField, ISpecVisitor, DomainError。对应地specs/下为每种匹配各提供一个原子 Spec 文件如FieldIsLinkSpec.ts、FieldIsComputedSpec.ts、FieldIsNumberFieldSpec.ts等构建器则负责把它们编排成可嵌套的规范树。值得一提的是实际目录中还包含 FieldSpecBuilder 依赖的FieldByKeySpec与FieldIsLookupSpec它们与FieldSpecs.spec.ts一起构成了该子包的完整验证闭环。七、visitors 子模块访问者模式驱动字段分派visitors/是模块中设计浓度最高的部分职责为字段访问者接口与默认实现启用子类型专属的分派逻辑见 visitors/ARCHITECTURE.md。接口层IFieldVisitorTIFieldVisitor.ts为 22 种字段类型各声明一个visitXxxField方法返回值统一为ResultT, DomainErrorAbstractFieldVisitor提供带默认链接字段处理的抽象基类NoopFieldVisitor则给出全空实现方便派生类只覆盖关心的类型。实现层visitors/目录下汇集了十数个各有专攻的访问者FieldValueTypeVisitor推导单元格值类型与多值性isMultipleCellValueFieldCellValueSchemaVisitor为单元格值生成 zod 校验 schemaFieldDefaultValueVisitor按字段类型生成默认值FieldFormVisibilityVisitor决定字段在表单视图中的可见性即 ARCHITECTURE 文档标注的按字段类型决定表单可见性FieldToSpecVisitor/SetFieldValueSpecFactoryVisitor把字段转换为规范、为写入记录构造SetValueSpecRecordWriteSideEffectVisitor记录写入时的字段联动副作用FieldOptionsDtoVisitor字段选项 DTO 转换SearchVectorFieldContributionVisitor字段对搜索向量的贡献normalizeCellDisplayValue/dateValueParser显示值与日期解析归一化。文档着重强调的四个跨表访问者如下节所述。所有访问者均有对应.spec.ts测试如FieldValueTypeVisitor.spec.ts、FieldFormVisibilityVisitor.spec.ts、FieldCellValueSchemaVisitor.spec.ts而 DefaultTableMapper.ts 则被作为如何完整实现一个 FieldVisitor的参考样例。八、跨表引用与创建/删除副作用链接、查找、汇总类字段天然横跨多张表因此模块提供专门机制管理跨表一致性ForeignTableRelatedField.ts接口 辅助函数用于在字段类型中校验跨表引用visitors/LinkForeignTableReferenceVisitor.ts从链接字段收集其引用的外部表集合visitors/FieldCreationSideEffectVisitor.ts计算字段创建引发的跨表副作用例如在目标表侧同步生成反向链接字段visitors/FieldDeletionSideEffectVisitor.ts计算字段删除的跨表副作用如清理另一张表上的关联字段。这组设计的验证由 ForeignTableValidation.spec.ts覆盖 rollup 外部表校验与FieldCreationSideEffectVisitor.spec.ts、FieldDeletionSideEffectVisitor.spec.ts覆盖链接字段增删副作用共同保障。从代码结构可以推断链接、汇总、查找字段的创建—引用—删除生命周期都由这组访问者驱动从而把跨表约束收敛到字段领域内部而不是散落在各应用服务里。九、函数式工具fieldPredicates除了面向对象的基类与访问者模块还提供一组轻量谓词函数fieldPredicates.ts直接基于FieldType判断类型并做类型收窄isFormulaField/isRollupField/isConditionalRollupField计算类字段isNumericFieldnumber/rating/autoNumber三类数值字段isDateField、isBooleanField日期与复选框isJsonValueField单元格值为 JSON 的attachment/user/button/multipleSelect。这些谓词与specs/中的规格互为补充规格面向可组合的查询/校验场景谓词则适用于代码中的即时类型判断与分支。十、测试与构建示例从文档到可运行的证据链ARCHITECTURE.md 末尾给出了两条入门路径均指向模块内真实文件字段创建FieldFactory.spec.ts —— 覆盖各字段类型的创建分支展示了id、name、options、expression等参数的组装方式是想新建一种字段时怎么写的最佳模板字段构建器用法TableBuilder.ts —— 表构建器示范了在建表这一更上层流程中如何编排FieldFactory与各类 Spec理解字段如何被组合进表领域模型。字段基类行为由 FieldBasics.spec.ts 守护值对象的校验规则由types/FieldValueObjects.spec.ts覆盖二者共同构成模块的回归防线。十一、小结fields 模块的设计启示纵观domain/table/fields其架构可以概括为三条正交轴实体轴抽象基类Field收敛共享状态与约束22 种子类型只实现accept与duplicate两个扩展点构造轴FieldFactory统一入口 applyFieldValidation后置校验保证任何路径创建的字段都满足非空/唯一约束行为轴Spec描述字段满足的条件与 Visitor按类型分派行为双模式解耦判断与动作跨表副作用、值类型推导、表单可见性等横切逻辑全部以访问者形式挂在基类上。对希望深入 Teable 或借鉴其领域建模的开发者而言fields/目录是一份高质量的值对象 工厂 Spec Visitor综合范例先读 ARCHITECTURE.md 建立全局图景再以 Field.ts 与 FieldFactory.ts 为入口逐层下钻即可快速掌握这套字段体系的完整运行逻辑。【免费下载链接】teable✨ AI Spreadsheet for Business项目地址: https://gitcode.com/GitHub_Trending/te/teable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表