1. 为什么偏偏是工业软件:最复杂的领域,才是检验“简单”的试金石
先聊一个可能有点反直觉的观察。很多人一听到“工业软件”,第一反应就是“越复杂越值钱”——毕竟里面装着几十年的数学算法、物理模型、行业规范,二维三维图形引擎、网格剖分、约束求解、数据管理,哪个拎出来都是硬骨头。我自己刚入行时也是这么想的,觉得把软件做得无穷复杂,就是技术实力的证明。但在这行待久了,接触过几代产品的演进,反而越来越确信一件事:工业软件这条赛道,表面上拼的是深度,实际上在“深度”之上还有一个更高的维度,就是做简化的能力。
这里说的“大道至简”,不是心灵鸡汤式的口号,而是一个可以被拆解、被验证、被复制到产品设计里的工程方法论。我把这套东西梳理出来,既是给自己团队做的复盘,也是写给所有做复杂软件、做B端产品、做平台型系统的朋友。不管你做的是CAE前处理、CAD内核、EDA流程管理,还是看似无关的企业级SaaS,只要你的软件面对的是复杂业务、多角色协作、长生命周期数据,这背后的法则都是相通的。
1.1 工业软件的复杂度究竟从哪来
工业软件的“复杂”不是开发者自找的,它有四个很现实的来源。理解了这四个来源,我们才知道所谓的“简单法则”到底是在和什么较劲。
第一,是多学科知识的耦合。一款正经的仿真软件,可能要同时处理几何造型、物理场求解、材料本构、边界条件、结果后处理;一款CAD工具,则要覆盖参数化建模、装配约束、工程图、BOM管理。每一个模块单独拎出来,都是一个垂直学科,但它们又必须在同一个平台里协同工作。这种天然的多学科耦合,让软件很容易变成“大杂烩”。
第二,是数据的长生命周期。工业数据不是用完就删的,一套产品设计数据可能要保存二十年甚至三十年。这几年大家常说“基于模型的定义”,把几何、工艺、仿真、制造信息全塞进一个模型里,数据之间的关联关系越来越密。面对这种长期演化的数据模型,任何一次想当然的“简化”,都可能引发历史数据的兼容灾难。
第三,是兼容性历史包袱。工业软件的生命周期是以十年为单位的,很多核心代码是从上世纪九十年代一路迭代过来的。用户现有环境里的脚本、插件、二次开发接口、历史文件格式,一样都不能破。这就导致“加一个新功能”往往比“改掉一个旧设计”容易得多,系统在这种博弈里逐年长胖。
第四,是组织流程的复杂性。一套研发管理平台要面对的角色可能包括设计工程师、仿真工程师、工艺工程师、项目经理、质量专员、采购人员,不同角色看到的数据、拥有的权限、使用的操作完全不同。这种来自组织维度的复杂度,往往比技术维度更磨人,因为它没有标准答案,只能靠持续摸索。
1.2 “大而全”的惯性,是创新最大的隐性成本
在和很多同行的交流里,我发现一个普遍现象:大家对“复杂”其实是又爱又恨的。爱的是它可以作为护城河——功能多、门槛高、别人短期追不上;恨的是它正在吞噬团队的效率——每加一个功能,维护成本就多一分,新人上手周期越来越长,缺陷率居高不下。
更麻烦的是,市场竞争和采购导向也在不断推着产品往“大而全”的方向走。很多潜在客户发过来的选型清单,动辄几百个功能点,商务要拿单,产品经理就得把功能矩阵填满。这种“以功能点数论英雄”的逻辑,逼着团队像搭积木一样往平台上堆东西,至于这些功能到底有没有人用、彼此之间是否自洽,反而没多少人真正关心。
这恰恰是“大道至简”最值得深挖的地方。真正的颠覆式创新,极少诞生在功能大爆炸的时候,而往往出现在有人敢于说“不”,敢于把一个庞大臃肿的系统重新收敛到核心范式的时候。我们拿工业软件做例子来谈这件事,就是因为它的复杂度是存量里最高的,容错率却又是最低的——在这样一个领域里能把简单做出来,那这套方法放在其他类型的软件上,基本都是降维适用。
2. 我理解的“简易法则”:四个可以在代码里验证的原则
翻了不少方法论的书,也看过很多“极简产品”的案例,到最后我会把“大道至简”拆成四个可以落地的原则,而不是一句抽象口号。这四个原则不解决“做什么功能”,而是解决“如何判断该留什么、该砍什么”,它们直接作用于产品设计和架构评审。
我认为一条卓有成效的路径,是把这条法则拆成四层来理解和运用,这也是我在实际产品和团队评审中不断验证出来的框架:约束先于功能、概念归一化、面向物理直觉、内核稳定而边界开放。
2.1 约束先于功能:主动制造边界,而不是被动响应需求
我遇到过的最常见场景,是产品评审会上有人提“要不我们加一个自定义材料库吧,反正开发量不大”。表面看,这个功能很合理;但如果每个“开发量不大”的需求都做进去,一个模块很快就会变得面目全非。我刚带项目时吃过这个亏——那是一个仿真参数设置界面,不到半年时间,从核心的三十几个参数膨胀到一百二十多个,连我们自己写帮助文档的人都快讲不清每个参数的适用场景了。
约束先于功能,意味着在动手之前,先明确这个模块“不做什么”。工业软件里最经典的例子是几何内核的对外接口:内核真正暴露给上层的,往往只有几十个核心API,但几千个上层功能全部构建在这几十个API的组合之上。这个API列表就是约束,它逼着上层设计在有限的机制里寻找表达力,而不是每来一个需求就扩充一个接口。
你可以这样操作:每次评审新功能时,强制要求提出者回答两个问题——第一,这个功能覆盖了哪个真实存在的用户场景,最好能说出具体用户和具体操作路径;第二,如果没有这个功能,用户用一个替代方案硬扛,损失会有多大。大部分拍拍脑袋想出来的需求,在这两个问题面前都会现出原形。这不是拒绝创新,而是把有限的研发资源集中在真正值得深入的地方,在一条窄而深的路径上做到极致。
2.2 概念归一化:用一个机制解释十种场景,而不是十种机制共存
工业软件发展了几十年,最典型的复杂度累积方式,就是为了解决一个个具体问题而不断引入新概念。以数据交换为例,行业里出现过几何数据交换标准、有限元结果交换格式、产品数据管理标准等一大堆规范,每个规范又伴随一套生成、解析、校验的工具。我见过某个平台的导入导出菜单里躺着二十多种格式选项,其中至少有一半连文档都不完整。
大道至简的一个重要动作,就是做“概念的收敛”。真正优秀的数据模型设计,会刻意追求用同一个抽象概念去解释尽可能多的场景。几何造型就是一个绝佳的例子:无论你是做一根轴、一个齿轮还是一个复杂的壳体,底层都可以统一到“边界表示”这一个概念上——用面、边、点的拓扑关系来描述任何三维形体。正因为它能覆盖所有形体,上层才可以放心大胆地只围绕这一套数据结构去做算法。
寻找归一化入口是有方法可循的。实操中我喜欢用一个“词语替换”练习:把需求文档里所有的名词画出来,看有多少个词其实指代同一个事物。比如把“设计版本”“工艺版本”“仿真版本”统一收敛为“数据状态”,整个数据模型瞬间就清爽了很多。归一化后的模型,往往还天然带来一个重大红利:因为核心机制更少,所以测试更充分、缺陷修复更快、二次开发的伙伴也更容易学会,这是一个正向飞轮。
2.3 让数据模型向工程师的物理直觉靠拢
第三层原则经常被忽视,但它恰恰是工业软件“用户体验”的灵魂所在。很多软件难用,不是功能不够,而是它的数据组织方式与一线工程师的思维习惯相悖。工程师脑子里想的永远是“这个零件在什么坐标系下,承受了多大的力,材料会不会屈服”,而你给的界面却是“树形目录-属性面板-参数分组-错误提示”,两边完全对不上。
让数据模型向物理直觉靠拢,意味着组织的层级、字段的命名、默认的参数值,都应该尽量贴近工程师熟悉的表达方式。一个简单但有效的检验方法:把软件界面截图给一位没做过软件开发的工程师看,问他“你觉得从这里到哪里能找到你想要的设置”,如果他要想超过五秒钟,那这个界面的组织逻辑就有问题。
我曾经参与过一个后处理模块的改版,旧版把“应力”“应变”“位移”分散在不同的菜单层级里,每次操作要切换好几个页面。我们做的事情很简单,就是按“工况—载荷—结果”三段式重新组织数据,把一个分析案例相关的所有数据收拢到同一个视图里。这个改动不涉及任何算法变更,但一线工程师的反馈是“终于能一口气把事干完了”。大道至简的落点,不在于技术本身有多玄妙,而在于你的简化能不能被用户直接感知到。
2.4 内核稳定,边界开放:把“变”和“不变”分开管理
这个原则是我自己重读架构设计时体会最深的一条,也几乎可以说是最务实的一条。很多团队做简化做不下去,是因为他们总觉得“一改就全得改”。但如果把系统分成“内核”和“边界”两部分,事情就清楚了:内核部分承载着最核心的数据模型和业务规则,必须保持稳定,宁可少改动也不轻易推翻;边界部分则是与外部的交互通道——插件接口、API、脚本语言、数据导出模板,这些区域要刻意设计成开放结构,允许持续演化。
我习惯用家具来做比喻:一张沙发的核心是它的框架和填充结构,这部分决定了坐感,不应该三天两头去改;而沙发套是可以换的,换一套就相当于给房间换了一种氛围。好的软件架构,沙发套一定比框架容易拆装得多。
具体到工业软件,内核稳定的典型动作包括:几何建模的拓扑规则、装配约束的类型定义、权限模型的基本语义,这些一旦定了就不要轻易变动;边界开放的典型动作则包括:对外提供脚本语言让用户自定义流程,开放插件标准让生态伙伴补充垂直能力,把算法参数通过配置文件暴露出来而不是写死在代码里。这种“稳定内核+开放边界”的设计,让简化不是一次性工程,而是一种可持续演进的状态,每一次迭代都只需要做局部调整,不至于牵连全局。
3. 简单法则在真实产品中的落地样本:三个我亲眼看过或亲手做过的案例
光讲原则容易让人觉得太虚,下面我用三个具体的产品场景来还原“大道至简”是怎么在真实世界里工作的。每一个案例都对应着我们上一节说的某条原则,也能看到简化后带来的直接收益。
3.1 从“功能矩阵”到“角色工作流”的重构
第一个案例是一款面向制造企业的数据管理产品。旧版主界面是按模块组织的,左边是“项目管理”“BOM管理”“文档管理”“变更管理”四个大分类,每个分类下又挂着十几个功能入口。整套界面乍看功能齐全,但新员工培训时普遍反应不知道从哪开始,老员工也经常点错。有时候为了完成一个审批流程,要反复在四个模块之间跳来跳去,非常别扭。
简化的时候,我们做了一个几乎不涉及底层代码、但效果极佳的改动:把原本按“功能类型”组织的导航,改成按“角色工作流”组织。设计工程师进来,第一眼看到的是“我的设计任务”“我的待办审批”“关联的变更单”;项目经理进来,第一眼看到的是“项目进度”“资源负载”“风险事项”。入口数量没有减少,但每个人需要的那几个都被聚拢在了最显眼的位置。
这个案例验证的正是“约束先于功能”加上“面向物理直觉”这两条原则的组合。约束不是指砍掉功能,而是指主动放弃“让一个界面讨好所有角色”的思路,转而把每个角色最常见的操作路径作为组织界面秩序的唯一标准。改动上线后,新员工上手时间从两周缩短到四天,内部支持工单数量也明显下降。用户不会说“界面好简洁”,而是会感觉“终于不用想就知道去哪点了” —— 这种自然感,就是简化成功的最直接信号。
3.2 组件化改造中的“节制之美”
第二个案例是一个工业仿真模块的组件化改造。老版本是一个单体程序,业务逻辑、界面渲染、数据访问全部混杂在一起,每次改动哪怕只是调整一个标签文案,也要重新编译整个模块,回归测试要跑大半天。团队当时有两个选择:一个是彻底推倒重构,按照微服务架构拆成十几个独立服务;另一个选择是只在保留核心数据模型的前提下,把界面渲染和业务逻辑拆开,做成插件式结构。
我们最终选了后者,而且刻意控制了拆分的粒度——只拆出三个核心组件:数据访问组件、计算调度组件、界面交互组件。为什么这么克制?因为工业软件最怕的就是服务拆分带来的数据一致性问题。如果为了追求架构上的“先进”而把计算核心变成远程服务,每一次求解都要经历网络传输和序列化,性能损耗是用户无法接受的;更何况很多仿真任务需要在本地闭环运行。
这次改造给我最大的启发,是“简”不等于“少”,而是“刚好”。组件的数量不是越少越好,也不是越多越“灵活”,而是要让每次变更的代价和风险的传播范围都足够可控。三个组件,恰好能让团队以很小的代价做独立开发、独立测试,同时不让数据流支离破碎。后来我给团队定了一条规矩:每次架构评审,多一个组件必须提交书面理由,说不清楚就合并回去。这条规矩看着有点蛮横,但它确实治住了那些“为了设计感而设计”的毛病。
3.3 一个反例:功能开关堆积出来的雪崩
第三个案例严格说是反面教材,是我在调研另一个团队的产品时看到的。那个产品为了兼顾不同行业客户的各种特殊需求,在系统里添加了几百个配置开关:模型同步开不开、字段长度限制是256还是512、审批流程是串行还是并行……每一项单独看都合情合理,但合在一起,系统变成了一个几乎无法预测的神秘黑盒。
有一次他们排查一个现场问题,客户现场的数据同步总是失败,团队远程看了半天日志都没头绪。最后派了工程师奔赴现场,才发现是客户在某个隐藏极深的开关组合下,触发了两个组件互相等待的死锁。事后复盘,问题的根子不在死锁逻辑本身——那只是一个普通的时序问题,而是几百个开关使得组合空间爆炸,测试根本无法覆盖到真实客户碰巧踩中的这个组合。
这个反例很好地说明,“大道至简”不是让你多占几个配置项就显得灵活,而是恰恰相反:每一个开关,都是在让系统的状态空间变得更大,都在消耗测试覆盖率和可支持性。真正优雅的设计,应该把“配置项数量”当成一个需要持续预算的指标,每新增一个,都意味着要对现有的几个潜在的组合关系做重新审视。复杂的系统从来都不是一夜之间变复杂的,它就是你今天同意加一个开关、明天同意加一个参数,温水和青蛙一样慢慢演变出来的。
4. 两个容易误解的“大道至简”:它既不等于砍功能,也不等于一步到位
我在实际分享这套方法论时,收到最多的两个质疑很有意思:一个说“你这是站着说话不腰疼,客户就要那些功能,砍了就没单了”;另一个说“简化我当然想,但历史包袱太重,根本没法一步到位”。这两个疑问,都源于对“大道至简”的两种理解偏差,有必要专门拆开来说清楚。
4.1 简化不是砍掉功能,而是压缩用户的认知成本
这是我需要反复澄清的一点。工业软件里很多功能是法律、标准或工艺要求的硬性需要,不是说砍就能砍的。比如某类压力容器的设计校核必须遵守固定的计算方法和报告格式,哪怕再“复杂”,你也得支持。
大道至简真正着力的,是“认知成本”而不是“功能数量”。这就是为什么在这一节里,我要把“功能数量”和“认知成本”两个指标分开来看。一款软件的复杂度感知,不是由功能总数决定的,而是由“用户为了完成一个任务需要记住多少东西、跳转多少个页面、理解多少个概念”决定的。
上面提到的角色工作流重构就是典型的例子:功能一个都没少,但认知成本大幅下降。还有一个我经常用的手法叫“三级渐进展示”:默认界面只显示最核心的5个参数,需要精细控制时可以展开第二级露出进阶参数,再到第三级才把工程师需要修改的高级选项显示出来。没有人会被功能淹没,但需要时功能都在。对一个仿真软件的求解设置界面来说,这种分级展示几乎适用于所有场景:不是把高级功能藏起来,而是不让它们阻碍新手用户完成最基本的操作。
4.2 简单不是起点,而是复杂之后的第二次攀登
另一个误解,是以为“简单”就是从零开始尽量少写代码。其实初期的简单大多是幼稚,是尚未暴露真实问题的简单。工业软件真正有价值的简化,一定发生在经历过全面复杂化之后的收敛阶段。我习惯用三个词来概括这个过程:第一版本是“单纯”,架构简单直接的单纯,因为系统还小,问题还没涌现;第二阶段是“复杂”,用户多了、场景杂了、团队为了应急不断打补丁,系统进入失控状态;第三个阶段才是“成熟”,是在看清了所有复杂性之后,重新找到高密度抽象和出口,让系统以更简洁的方式承载同样的功能。
所以我完全理解为什么有团队一听到“简化”就头疼——因为他们正处于第二阶段,系统里每一个补丁都对应着一个当时必须照顾的现实约束。但我们恰恰需要在第二阶段去做收敛,而不是指望通过一次天翻地覆的重写来逃离。收敛的方式就是之前说的几个原则的综合使用:用归一化概念替代分散的多个机制、用角色工作流重构界面、用稳定内核保护核心数据模型。这条路不会让你瞬间变得“简单”,但它会让你每一步都离简单更近一点。
在这个阶段,我还想特别提醒一件事:删代码和留代码需要同样大的勇气。很多团队做简化的障碍不是不知道某个模块该删,而是担心“万一以后又要用呢”。我自己的经验是,与其让一段三年没人调用的代码继续躺在系统里占据大家的认知,不如把它挪到一个专门的“历史兼容区”,标记清楚。这样既不破坏潜在兼容性,也让主路径的代码量大幅下降。这不是取巧,而是给代码同样划出一条稳定的“内核线”。
5. 团队与产品:让“简单”成为可持续的制度,而不是某个人的灵光一现
讲完了方法论和案例,最后回到一个我越来越觉得重要的问题:大道至简如果只是产品经理或架构师个人的偏好,那它一定无法持久。只要组织做出一个复杂决策的激励机制还在,系统的复杂度就一定会缓慢回升。所以要让“简单”真正成为软件的一种长期品质,必须把它落成组织的制度。
5.1 组织形态先于产品形态:康威定律的另一面
很多年前我在给新人培训架构设计时总会提到康威定律:产品的架构会趋同于组织的沟通结构。后来我发现,这条定律的魔性不仅仅体现在架构上,更体现在复杂度的分配上。如果一个公司里同时有三个部门各自维护着三个有重叠功能的产品模块,那用户界面上就必然会冒出三套相似但不同的操作方式;如果考核指标只看新功能上线速度,那代码仓库里就必然会堆满临时的 patch。
因此,想让产品变简单,先要回答团队结构的问题:有多少人真正对“全局体验”负责?这个责任人有没有权限否决来自各个业务方的复杂需求?如果没有一个明确的“复杂度责任人”,那各个团队自然会从自身局部利益出发给产品加东西,最终复杂度一定失控。
这些年我的一个组织实践是设立“开发者体验小组”,成员的 kpi 不是新增功能数量,而是“全流程任务完成时长”“新功能用户无帮助使用的完成率”“二次开发接口的文档覆盖率”。这个小组有一项特殊权力:可以打回任何没有用户调研支撑的产品需求。说实话,刚开始推行时阻力不小,但坚持了一两个版本后,连销售同事都开始觉得“能讲清楚、能当场演示的功能”反而更容易签单。
5.2 每个人都可以立刻练起来的“简化基本功”
组织制度是长期的事,但对每一个工程师、产品经理、技术管理者来说,有一些动作今天就可以开始做,而且不需要任何领导审批。
第一,给模块写一句话说明。如果一句话说不清楚这个模块是干什么的,那这个模块的设计大概率是有问题的。这句说明不是给领导的汇报材料,而是给半年后的自己看的。写不出来,就是提醒你需要重新梳理这个模块的边界。
第二,做三十秒全流程测试。每季度挑一个核心用户旅程,从登录开始,要求自己在三十秒内点完关键操作路径。超时就说明主路径上混入了太多干扰项,需要清扫。
第三,做新增功能的季度复盘。每个季度末翻一下过去三个月上的新功能,调用日志会告诉你哪些真的有用户在用。我自己的经验是,超过一半的新功能在季度末的日活统计里趋近于零。把这些数据摊在桌上,下一次讨论“要不要再做一个新功能”时,大家会理性很多。
最后,如果让我在这么多年的实践经验里提取一句话给后来者,那就是:做复杂软件最容易的路径是顺着惯性叠加复杂度,最难也最值钱的路径,是在每一个决策点都问一句“这个必要吗”。工业软件如此,其他任何软件也是如此。它能让你做出来的东西,在一堆功能臃肿的竞品里,成为用户愿意长期留驻的“那个安静但可靠的选择”。如果你正在做一个越来越胖的产品,不妨就从下个迭代开始,试着砍掉一个连你自己都不太确定用途的设置项。那份如释重负的感觉,会自动告诉你方向是对的。