首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >一个架构师的自白:当系统开始"说谎",我如何找到真相

一个架构师的自白:当系统开始"说谎",我如何找到真相

作者头像
智谷星瀚
发布2026-03-31 16:30:03
发布2026-03-31 16:30:03
980
举报
文章被收录于专栏:AI实验室应用AI实验室应用

前几天,我在做一个智能投标管理系统的编辑器优化。

用户反馈说:"全局样式设置了,但没有生效。"

我第一反应是:应该是哪里漏传了参数。翻代码,找到对应的 store,逻辑完全正确,状态也存进去了。但就是没生效。

然后我意识到:系统在说谎。


一、当系统开始说谎

什么叫系统说谎?

就是代码逻辑没有问题,测试也能通过,但实际运行的结果和你以为的完全不一样。这种情况往往不是 bug,而是架构层面的裂缝

这个项目的背景是这样的:系统有一个标书编制页面,用户可以选择章节、编辑内容、设置排版样式。排版样式(字体、字号、行距)存在全局 store 里,理论上所有章节打开时都应该自动应用。

但用户说没有生效。

我开始追代码。发现了一件有意思的事情:

这个系统里存在两套编辑器

一套是 BidCompose.tsx,是最早写的独立页面编辑器。另一套是 SectionEditor.tsx,是后来在工作流模块里新加的章节编辑器。排版面板、全局样式的逻辑,只在 SectionEditor 里实现了。而用户实际使用的入口,是 BidCompose

所以全局样式存进去了,但压根没有人去读它、应用它。

这就是系统在说谎的方式:功能看起来存在,实际上是孤岛。

我把这种情况叫做「功能分裂」。它是一种比 bug 更危险的问题,因为它不会报错,不会崩溃,只会悄悄让用户的期望落空。


二、根因不在代码,在决策

找到问题根因之后,我没有急着修。

我先问了自己一个问题:为什么会有两套编辑器?

这不是代码层面的问题,而是一个决策问题。

回溯历史,大概率是这样的:一开始有一个简单的编辑器(BidCompose)。后来做工作流功能时,需要一个更强大的章节编辑器,于是新建了 SectionEditor,把排版、字数统计、AI 生成等功能都堆进去了。两套并行,互不感知。

这是产品快速迭代时非常常见的模式:在已有系统旁边新建,而不是改造已有系统

短期看这样很快,不会破坏现有功能。长期看,系统会逐渐分裂成多个"平行世界",每个世界有自己的逻辑,彼此不同步。

修复这种裂缝,比修一个 bug 要难得多——因为你不只是在改代码,你是在弥合两个架构决策之间的鸿沟

我的选择是:不合并两套编辑器(代价太大),而是在 BidCompose 里补上缺失的那一半逻辑,让它也能读取和应用全局样式,并加上排版面板。同时把 BidCompose 作为唯一的主入口,让 SectionEditor 继续服务工作流场景。

这个决策的本质是:承认分裂,但设定边界。


三、一行 CSS 背后的架构问题

第二个问题更有意思。

用户反馈:「编辑内容很长时,顶部的工具栏会随着滚动消失,想用某个功能还得往回滚。」

这是一个经典的「工具栏 sticky 失效」问题。我看了一眼代码:

代码语言:javascript
复制
.rich-text-editor {
  overflow: hidden;  /* ← 就是这里 */
  border-radius: 8px;
}

.toolbar {
  position: sticky;
  top: 0;
  z-index: 10;
}

工具栏已经设置了 sticky top-0,但外层容器有 overflow: hidden

很多人不知道一个 CSS 规范里的细节: 定位只在可滚动祖先容器内生效。而 会创建新的溢出上下文,直接使 失效。

这是表层原因。但我想聊聊更深的那一层。

为什么外层容器会有 overflow: hidden

因为要实现圆角(border-radius)时,防止子元素溢出破坏外观。这是一个非常合理的样式决策,在大多数场景下都没问题。

但问题在于:这两个决策没有在同一个上下文里被考虑过。加圆角时没有想到工具栏需要 sticky,加 sticky 时没有意识到外层有 overflow 截断。

这就是我理解的「容器职责混乱」:一个容器同时承担了「视觉容器」(圆角、边框)和「滚动上下文」两种职责,而这两种职责在某些情况下是互斥的。

解法很简单:去掉 overflow: hidden,工具栏加 shadow-sm 来实现视觉分离。但这个解法背后的思维是:识别并分离容器的职责


四、用户在想什么,你的系统却不这么想

第三个问题,是我认为这轮迭代里最有价值的一个决策。

原来的流程图编辑器,是一个 Mermaid 代码编辑器——左边写代码,右边实时预览。对于会写 Mermaid 语法的人来说,效率很高。

但这是一个面向招投标从业者的系统,不是面向程序员的。

用户反馈:「流程图节点不能拖,不能修改,就像看着一个图,但完全没法编辑。」

这句话让我停下来想了很久。

用户在想什么?

用户在想:这个框框,我要把它移到那里;这条线,我要让它弯一点;这个菱形,我想让它大一点,文字小一点。

系统在想什么?

系统在想:你需要写 flowchart TD 然后用 --> 连接节点,用 { } 表示菱形,用 [ ] 表示矩形……

这就是用户心智模型和系统模型的错位

用户的心智模型是「画图」,系统给的是「写代码」。两者在表达同一件事,但认知成本差了一个数量级。

我用 React Flow 重写了流程图编辑器。现在用户可以直接拖拽节点、调整大小、从蓝色连接点拖出连线、在属性面板里改颜色和字号。技术上实现起来比 textarea 复杂很多,但用户感受到的是:「哦,这就是我想要的。」

好的架构,应该让系统和用户说同一种语言。


五、模式,是一种认知框架

最后一个决策,是关于「预览」和「编辑」的关系。

原来的设计是:进入页面默认是编辑模式,点「预览」会弹出一个全屏遮罩,预览完关掉继续编辑。

用户说:「我希望进来先看整篇文章的排版效果,然后点某个章节再去编辑。」

这句话改变了我对这个页面的理解。

原来我认为:编辑是主任务,预览是辅助确认。

用户告诉我:预览才是起点,编辑是后续动作。

这不只是顺序的调整,而是对用户工作流的重新理解

一个写招标文件的人,他的工作流是这样的:先看整体,再局部调整,再看整体……这是一个反复在「全局视角」和「局部编辑」之间切换的过程。

所以我把「预览」从弹窗变成了内嵌的主视图,默认进入时展示整篇预览。顶部有两个切换按钮:「预览」和「排版编辑」。在预览里点击某个章节,可以直接跳转到对应的编辑状态。

这个改动的工作量不大,但背后的思维转变很重要:模式(mode)不是功能,是用户的认知框架。

设计「模式」时,你需要问的不是「这个功能放在哪里」,而是「用户在哪个心理状态下需要这个功能」。


六、架构师的工作,是给系统找到自己的语言

回顾这三轮迭代,我发现自己做的事情,本质上只有一件:

让系统更诚实。

  • • 修复功能分裂,是让系统不再撒谎「我有这个功能」
  • • 修复 sticky 失效,是让系统不再撒谎「工具栏一直在」
  • • 重写流程图编辑器,是让系统开始说用户听得懂的话
  • • 重新设计预览/编辑模式,是让系统的流程和用户的流程对齐

架构师最重要的能力,不是选择哪个框架、用哪种设计模式。而是能够持续感知系统和现实之间的偏差,然后找到代价最小的方式把它们重新对齐。

每一次对齐,都是一次架构的进化。


最后分享一个我反复验证过的判断标准:

当用户说「这个东西没用」,通常不是功能不存在,而是功能和用户的期望之间有一道看不见的墙。架构师的工作,就是找到这道墙,然后把它拆掉。

不是加功能。是拆墙。


本文基于智能投标管理系统近期迭代的真实经历,技术栈:React 18 + TypeScript + Tiptap + React Flow。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI实验室应用 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、当系统开始说谎
  • 二、根因不在代码,在决策
  • 三、一行 CSS 背后的架构问题
  • 四、用户在想什么,你的系统却不这么想
  • 五、模式,是一种认知框架
  • 六、架构师的工作,是给系统找到自己的语言
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档