设计约束
影响系统设计的约束
这篇文章要回答什么?
Section titled “这篇文章要回答什么?”前面的章节已经讨论了:
- 组件为什么可以被当作协议来理解
- 原型如何通过信息通路来组织交互关系
- 原型边界为什么不能随意切分
- 执行语义如何约束原型在时间中的成立方式
- 原型为什么必须通过翻译层才能进入宿主
接下来的问题是:
Proto UI 为什么没有把自己做成一个无限开放的抽象系统?
这一篇要讨论的是:
- Proto UI 主动接受了哪些设计约束
- 这些约束如何影响原型、语法和翻译层
- 为什么这些约束不是临时退让,而是系统长期成立的条件
约束不是补丁,而是边界
Section titled “约束不是补丁,而是边界”任何试图协议化描述 GUI 的系统,都会很快面对一个诱惑:
既然已经开始抽象,那是否应该把更多问题都纳入核心层?
这个方向看起来很自然,但通常也最容易失去边界。
因为一旦一个系统什么都想表达,它很快就会开始同时承担:
- 平台能力的细节差异
- 各宿主的工程习惯
- 各种局部实现便利
- 作者个人的书写偏好
- 更高层的业务编排与 UI 组织问题
到那时,抽象虽然还存在,但它已经不再稳定。
它会越来越像一层不断扩张的工程接口,而不是一套可迁移、可验证的协议基础。
Proto UI 从一开始就没有打算把所有 GUI 问题吞进核心层。
它更关心的是另一件事:
在不失去边界的前提下,保住最关键的交互语义。
这就是设计约束的起点。
Proto UI 的取舍顺序
Section titled “Proto UI 的取舍顺序”Proto UI 的很多工程决策,最终都会落到同一条排序上:
语义一致 > User 体验 > Maker 体验 > 原型 Author 体验
这条顺序并不意味着后面的事情不重要。
它只是说明:当这些目标彼此冲突时,Proto UI 会按这个优先级做取舍。
第一优先级是:
同一个原型在不同适配结果中,是否仍然是同一个交互主体。
这决定了 Proto UI 能否被称为协议层。
如果语义一致性被让位,后面的体验再好,也只是在不同宿主里分别写出了一些“彼此相关”的实现。
User 体验
Section titled “User 体验”在语义一致之后,Proto UI 优先考虑的是最终用户的体验。
这包括:
- 交互是否稳定
- 反馈还原度是否足够高
- 性能是否可接受
- 宿主中的真实体验是否自然
Proto UI 不把“协议正确”理解成只在文档中成立。
它最终仍然要落到用户真的会感受到的交互质量上。
Maker 体验
Section titled “Maker 体验”再往后,才是 Maker 的使用体验。
这里的 Maker,指的是在宿主里消费 Proto UI 产物的人或系统。
这一层关心的是:
- 组件是否符合宿主开发者的使用习惯
- Adapter / Compiler 生成的结果是否容易接入
- 使用方式是否足够自然
它很重要,但它仍然让位于前两层。
原型 Author 体验
Section titled “原型 Author 体验”最后才是原型作者自己的开发体验。
Proto UI 当然关心原型语法是否可写、是否易读、是否易维护,
但当 author 体验与前面几层发生冲突时,它不会自动优先 author。
这也是为什么 Proto UI 的某些约束看起来会偏严格。
有些限制并不是因为没有更方便的写法,
而是因为更方便的写法更容易破坏前面几层更重要的目标。
Proto UI 先保护交互主体,再考虑表达自由
Section titled “Proto UI 先保护交互主体,再考虑表达自由”Proto UI 的第一性原理之一,是:
原型必须描述一个交互主体。
这意味着,一个原型不能只是任意结构片段,也不能只是视觉树上的一段局部模板。
它必须始终指向一个能够成立的交互主体。
从这个前提出发,Proto UI 的很多约束都会变得更容易理解。
例如:
- 原型默认总是作用于当前原型自身
- 子结构一旦承担独立信息通路责任,就必须拆分
- 某些语法能力不会被开放给仍然留在父原型内部的结构
这些限制表面上看像是在收紧写法,
实际上是在保护“原型描述的究竟是谁”这件事不被写散。
Proto UI 不把自己做成框架
Section titled “Proto UI 不把自己做成框架”Proto UI 的目标是稳定组件层的交互语义,
而不是接管最终 UI 的组织方式。
这意味着,Proto UI 默认不主动承担:
- 业务接合层
- 原型之间的最终组合
- 框架级别的复杂场景调度
- 各宿主中特有的高层 UI 组织问题
Proto UI 允许原型层发生逻辑复用,
例如把另一段原型逻辑融入当前原型中。
这种复用更接近 hook 调用或继承,处理的是逻辑能力的吸收,而不是最终 UI 的结构组合。
但原型之间如何被拼接成完整界面,如何进入具体业务,如何在更复杂的场景下被调度,
这些事情默认回到宿主侧处理。
这条边界不是偶然选择。
它对应的是 Proto UI 对自身位置的判断:
Proto UI 要做的是组件,而不是最终 UI。
社区当然可以在 Proto UI 之上继续发展更完整的框架能力,
但这不是 Proto UI 官方当前要优先解决的问题。
边界不只靠文档说明,也会体现在语法能力里
Section titled “边界不只靠文档说明,也会体现在语法能力里”Proto UI 的一些边界,并不只是写在说明文里的原则。
它们还会进一步体现在语法能力的取舍上。
例如,Proto UI 不会默认给作者提供“在不拆分子结构的前提下,让子结构承担完整独立信息通路责任”的能力。
这意味着原型边界不是一种纯靠自觉维持的写作风格,而是会在写作过程中被直接约束。
这种做法会收紧表达自由,
但它也减少了另一类代价更高的问题:
- 交互责任边界被悄悄写散
- 原型重新退化成结构拼装系统
- 同一个原型到底在描述谁变得越来越不清楚
Proto UI 在这里的取向是明确的:
先把边界固定下来,再考虑如何在边界之内提高表达效率。
可序列化是一个长期方向约束
Section titled “可序列化是一个长期方向约束”Proto UI 现阶段还有一个很强的约束倾向:
协议层默认优先采用可序列化的表达。
这条约束并不只服务于当前实现。
它更多是在为后续的翻译、验证和更静态的产物生成铺路。
如果协议层过早接受大量不可序列化的默认语义,例如:
- 任意函数
- 平台对象
- 宿主专属引用
- 无法稳定迁移的运行时值
那么短期内也许会更方便,
但长期来看,协议层会立刻失去几个重要特征:
- 更难分析
- 更难验证
- 更难编译
- 更难稳定迁移到新的宿主
因此,Proto UI 并不是完全拒绝这些能力的存在,
而是默认不把它们作为协议层的主语义。
这条约束会让当前的表达方式显得更克制,
但它换来的,是后续更大的翻译空间与更稳定的长期演进路径。
宿主特有能力更适合作为强宿主相关能力处理
Section titled “宿主特有能力更适合作为强宿主相关能力处理”类似的取向也体现在宿主特有能力上。
Proto UI 可以承认很多能力非常重要,
但重要并不自动意味着它们都应进入核心主轴。
有些能力:
- 天然高度依赖宿主
- 很难跨平台迁移
- 在不同宿主之间缺乏稳定可比性
这类能力更适合被隔离为强宿主相关能力,
而不是直接进入核心协议层。
host 通路就是一个很典型的例子。
它当然重要,但它更接近宿主本身,也更容易被具体平台的现实条件牵着走。
Proto UI 在这里的做法并不是否认它的价值,
而是把它放在一个更谨慎的位置上处理。
这种做法会让核心层显得偏克制,
但它也让 Proto UI 的跨宿主主轴保持得更稳定。
这些约束保护的是什么?
Section titled “这些约束保护的是什么?”把这些约束放在一起看,它们保护的其实是同一件事:
Proto UI 不希望自己的抽象边界在工程便利中逐渐融化。
如果没有这些约束,Proto UI 当然可以变得更灵活:
- 原型可以更随意地嵌套
- 子结构可以更自由地承担局部交互
- 协议层可以更快接纳宿主特有能力
- 原型 author 写起来也可能更顺手
但代价也很明确:
- 原型边界会变得模糊
- 协议层会变得更难验证
- 可迁移性会逐渐下降
- 翻译层会被迫接收越来越混杂的输入
- “同一个原型”这件事会越来越难成立
Proto UI 的设计约束,就是为了避免这条滑坡。
这不是保守主义
Section titled “这不是保守主义”这些约束很容易给人一种印象:
Proto UI 是不是只是选择了更保守的路线?
如果只看表面形式,确实会有这种感觉。
但这里真正发生的事情,并不是“因为能力不足,所以先不做”,
而是:
为了让协议层长期成立,某些边界需要先被保护。
Proto UI 当然可以在未来逐步放宽某些约束,
也可以在更成熟的工程条件下接纳更多能力。
但它不希望在抽象尚未站稳的时候,就把过多现实复杂度直接卷进核心层。
因此,这里的克制并不是退让,
而是一种先后顺序上的选择:
- 先让协议层成立
- 再决定哪些边界值得被扩展
这一篇没有展开什么?
Section titled “这一篇没有展开什么?”为了保持主线清晰,这一篇不会继续展开:
- 正式规范条文
- 具体工程实现细则
- 宿主能力矩阵
- 具体版本的里程碑计划
这些内容会在 Specifications 与 Engineering 章节中继续展开。
如果这些设计约束已经成立,那么接下来的阅读重点就不再是:
Proto UI 想表达什么?
而会变成:
这些边界在正式规范与工程实现中,究竟是如何被落下来的?
你可以按自己的目标继续往下读:
- 如果你想继续澄清边界与常见疑问:前往 FAQ
- 如果你想查阅正式契约:前往 Specifications / 规范导读
- 如果你想理解实现层如何承接这些原则:前往 Engineering / 工程导读
- 如果你已经想尝试参与原型或适配器建设:前往 Ecosystem / 生态导读