软件设计不要“既要又要”

做软件久了,我总结很多设计问题最终都不是技术问题,而是取舍问题。

需求讨论时,经常会听到这样的声音:

  • 能不能立即生效?
  • 能不能一步完成?
  • 能不能满足所有用户?
  • 能不能功能丰富又简单易用?
  • 能不能灵活配置但不增加复杂度?

换句话说:

既要这个,又要那个。

遗憾的是,软件设计很少存在完美方案。

大多数时候,我们面对的不是对错,而是权衡。

优秀的软件设计,往往不是实现了所有需求,而是在收益、复杂度、风险和成本之间做出了合理选择。


一个真实案例:底部导航排序

假设你的 App 支持用户自定义底部导航栏顺序。

用户原来的导航顺序是:

复制代码
首页
任务
发现
我的

调整为:

复制代码
任务
首页
我的
发现

很快就会产生一个问题:

用户点击保存后,是否需要立即生效?

很多人的第一反应是:

当然要立即生效。

毕竟用户刚修改完成,总应该马上看到结果。

但从工程实现角度看,事情没有这么简单。

如果立即生效,可能需要处理:

  • 导航结构重建
  • 页面状态迁移
  • 当前路由恢复
  • 输入框内容保留
  • 滚动位置恢复
  • 页面缓存同步
  • 动画过渡处理

更麻烦的是,如果用户正在编辑内容:

erlang 复制代码
今天完成了项目复盘...

此时导航栏重建,可能导致:

  • 输入内容丢失
  • 页面重新渲染
  • 当前状态异常

而用户真正获得的收益是什么?

只是:

复制代码
点击保存后立刻看到顺序变化

收益存在,但并不大。

于是另一种方案出现了:

复制代码
导航顺序已保存

将在下次启动应用后生效

这个方案:

  • 开发成本更低
  • 测试成本更低
  • 系统风险更低
  • 不会影响用户当前操作

同时用户的目标仍然被满足。

因为用户真正想要的是:

复制代码
以后使用时按照新的顺序显示

而不一定是在当前这一秒看到变化。

这个例子让我越来越相信:

软件设计不应该只讨论"能不能做",而应该讨论"值不值得这样做"。


用户提出的,未必是用户真正需要的

很多开发者会把用户提出的需求直接翻译成产品功能。

实际上,用户表达的往往是解决方案,而不是问题本身。

例如用户说:

复制代码
我要导出 Excel

很多团队立刻开始设计:

  • Excel 模板
  • 导出任务
  • 导出权限
  • 导出历史

但在开发之前,应该先问一个问题:

为什么需要导出 Excel?

答案可能是:

复制代码
我要把数据发给同事

这时候产品设计的空间就出现了。

可以考虑:

方案一:

复制代码
导出 Excel

方案二:

复制代码
生成分享链接

方案三:

复制代码
生成 PDF

方案四:

复制代码
直接调用系统分享

最终可能发现:

用户只是想把数据传递给别人。

而导出 Excel 只是其中一种方式。

软件设计的重要工作之一,就是找到用户真正要解决的问题,而不是机械地实现用户提出的方案。


用户需求和产品设计不是一回事

还有一种常见情况。

开发者会把所有用户未来可能需要的信息,都放到注册流程里。

例如:

复制代码
手机号
验证码
昵称
头像
性别
生日
地区
职业
兴趣爱好
实名认证

从产品角度看:

这些信息以后可能都会用到。

于是全部放进注册流程。

逻辑似乎很合理。

但从用户视角看:

复制代码
我刚打开应用。

我还不知道这个产品值不值得我使用。

此时要求填写大量资料,其实是在增加用户成本。

更合理的设计通常是:

第一次进入:

复制代码
手机号 + 验证码

即可。

需要添加好友时:

复制代码
请设置昵称

需要参与社区时:

复制代码
请上传头像

需要涉及身份认证的功能时:

复制代码
请完成实名认证

这种设计有一个明显优势:

用户是在获取能力的过程中完成资料,而不是在进入产品之前完成资料。

同样的信息收集需求。

体验却完全不同。


每一个功能都不是免费的

很多需求评审会上,经常有人说:

复制代码
这个功能也不难做。

事实上,一个功能的成本从来不只是开发时间。

它还意味着:

  • 更多代码
  • 更多状态
  • 更多测试用例
  • 更多文档
  • 更多 Bug
  • 更多维护工作

功能上线只是开始。

维护才是长期成本。

很多团队低估了维护成本,高估了功能收益。

结果产品越来越复杂,开发效率越来越低。


为什么优秀产品都在做减法

当你研究苹果、Google 以及大量优秀产品后,会发现它们背后其实遵循着一些相似的设计原则。

渐进式披露(Progressive Disclosure)

这是 Apple Human Interface Guidelines 和 Google Material Design 都在强调的理念。

核心思想是:

只在用户需要的时候展示复杂功能和信息。

用户第一次打开产品时,应该尽快获得价值。

而不是先完成一堆配置。

前面提到的资料填写案例,本质上就是渐进式披露。

不是不收集资料。

而是在合适的时候收集资料。


KISS 原则

软件工程中的经典原则:

Keep It Simple, Stupid.

在满足需求的前提下,选择最简单的方案。

导航栏排序案例就是典型例子。

如果:

复制代码
下次启动生效

和:

复制代码
立即生效

都能满足用户目标。

那么更简单、更稳定、更容易维护的方案往往更值得选择。


YAGNI 原则

敏捷开发中的经典理念:

You Aren't Gonna Need It.

不要为未来的假设需求提前买单。

很多产品喜欢预先设计:

  • 插件系统
  • 工作流系统
  • 高级权限系统
  • 无限扩展能力

理由通常是:

复制代码
以后可能会用到

但现实往往是:

复制代码
一年后都没人使用

提前实现这些能力,带来的往往是复杂度,而不是价值。


Don't Make Me Think

这是可用性设计领域最经典的原则之一。

核心思想是:

用户不应该思考软件应该如何使用。

如果用户想把数据发给同事。

那么设计目标应该是:

复制代码
快速分享数据

而不是:

复制代码
导出
↓
保存
↓
打开微信
↓
选择文件
↓
发送

好的设计会尽可能缩短用户完成目标的路径。


聚焦用户当前最重要的任务

Google Material Design 强调:

Focus on the user's primary task.

用户打开产品时,总有一个最重要的目标。

例如:

打开 OKR 应用。

用户真正想做的可能是:

  • 查看目标
  • 记录进展
  • 完成任务

而不是:

  • 修改主题颜色
  • 调整导航顺序
  • 自定义按钮样式

优秀产品会优先把资源投入到核心任务,而不是边缘功能。


软件设计是一门权衡的艺术

在工程领域有一个广泛认同的观点:

Every design decision is a trade-off.

每一个设计决策都是权衡。

增加一个功能,可以提升体验。

但也会增加复杂度。

提高实时性,可以增强反馈。

但也会增加状态管理难度。

增加灵活性,可以覆盖更多场景。

但也可能让系统更难维护。

真正成熟的设计,不是追求所有指标同时最优。

而是明确:

  • 用户获得了什么收益?
  • 为此付出了多少复杂度?
  • 引入了多少风险?
  • 后续维护成本是否值得?

然后做出最合理的选择。


我现在做需求时会问的几个问题

每当准备增加一个功能时,我都会先问自己:

  1. 用户真正要解决的问题是什么?
  2. 用户提出的是需求,还是某种实现方案?
  3. 有没有更简单的实现方式?
  4. 收益是否足以覆盖复杂度?
  5. 后续维护成本是否值得?
  6. 如果不做,会产生什么实际影响?

很多时候,答案并不是:

复制代码
马上开发。

而是:

复制代码
先等等。

或许有更简单的办法。

结语

软件设计最大的陷阱之一,就是总想"既要又要"。

既要实时生效,又要零风险。

既要功能丰富,又要绝对简单。

既要覆盖所有场景,又要没有维护成本。

现实中很少存在这样的方案。

优秀的软件设计不是不断做加法。

而是在有限的时间、资源和复杂度中,找到最值得做的事情。

学会取舍,比学会实现更重要。

因为决定一个产品质量上限的,往往不是写了多少代码,而是放弃了多少不必要的代码。


延伸阅读

如果你对产品设计、用户体验以及软件复杂度控制感兴趣,下面几本书非常值得阅读。

这些书中的很多思想,都与本文讨论的"不要既要又要""学会做取舍"不谋而合。

《结网》

作者:王坚

国内产品经理领域非常经典的一本书。

相比介绍工具和流程,《结网》更关注产品设计背后的思考方式。

书中大量案例都在讨论:

  • 用户真正需要什么
  • 如何理解用户行为
  • 如何平衡产品目标与用户体验
  • 为什么很多看似合理的需求其实并不值得做

对于互联网产品从业者来说,这是一本非常好的入门书籍。


《点石成金》(原书名:Don't Make Me Think)

作者:Steve Krug

可用性设计领域的经典著作。

书名本身就是核心观点:

不要让我思考。

很多产品问题并不是功能缺失,而是用户完成目标的路径过于复杂。

当用户想要完成一件事时,设计应该帮助他快速达成目标,而不是增加额外步骤。

对于开发者来说,这本书最大的价值在于:

它会让你开始用用户视角重新审视自己的产品。


《设计心理学》(原书名:The Design of Everyday Things)

作者:Don Norman

用户体验领域的里程碑作品。

虽然讲的是广义设计,但很多思想同样适用于软件设计。

例如:

  • 为什么用户会犯错
  • 为什么复杂系统容易产生误操作
  • 为什么设计应该符合人的认知习惯

读完之后,你会发现很多软件问题其实并不是用户不会用,而是设计本身存在问题。


《启示录:打造用户喜爱的产品》(原书名:Inspired)

作者:Marty Cagan

产品管理领域的经典著作。

书中反复强调一个观点:

用户不会告诉你正确的产品方案。

用户能够描述问题。

产品团队需要负责寻找解决方案。

这与本文提到的:

复制代码
用户说要导出 Excel

实际上可能只是想把数据发给同事

属于同一种思维方式。


《精益 UX》(原书名:Lean UX)

作者:Jeff Gothelf

很多团队喜欢在需求评审阶段争论:

复制代码
用户一定会喜欢这个功能

这个功能以后肯定会用到

而 Lean UX 提倡:

不要猜测。

尽可能通过最小成本验证假设。

这与软件工程中的:

rust 复制代码
YAGNI
You Aren't Gonna Need It

有异曲同工之处。


《程序员修炼之道》(原书名:The Pragmatic Programmer)

作者:Andrew Hunt、David Thomas

虽然这是一本软件工程书籍。

但它对于复杂度控制的理解非常深刻。

书中有一个贯穿始终的思想:

每一个决策都会产生长期成本。

软件设计不仅是在设计功能。

也是在设计未来的维护成本。


《精要主义》(原书名:Essentialism)

作者:Greg McKeown

这是我认为与本文主题最契合的一本书。

它讨论的并不是产品设计,而是如何在有限资源下聚焦最重要的事情。

核心思想可以浓缩为一句话:

Less, but better.

少做,但做得更好。

如果把这句话放到软件设计领域,也同样成立:

不是功能越多越好。

而是解决用户核心问题的能力越强越好。

相关推荐
X54先生(人文科技)2 小时前
《元创力》纪实录·卷宗2.1P上去的安全带:当“表演性合规”成为文明的遮羞布
人工智能·架构·开源·ai写作·开源协议
柏舟飞流2 小时前
Spring Boot 深入实践指南:从入门到工程化落地
spring boot·后端·firefox
kyriewen3 小时前
从Webpack到Vite:我们迁移了一个10万行代码的项目,总结了这7个坑
前端·webpack·vite
IPHWT 零软网络3 小时前
信创场景下大容量语音网关的架构设计与实践——以 MX120G-A 为例
架构·信创·国产化·语音网关
IT_陈寒3 小时前
Java Stream并行流的坑:我花了3小时才找到的线程安全问题
前端·人工智能·后端
小新1103 小时前
最简单但完整的 Vue 响应式示例(一个简单的计数器按钮)
前端·javascript·vue.js
橘子海全栈攻城狮3 小时前
【最新源码】鸟博士微信小程序 023
spring boot·后端·web安全·微信小程序·小程序
Hiter_John3 小时前
Golang的运算符
开发语言·后端·golang
皮皮林5513 小时前
Dubbo 的 SPI 和 JDK 的 SPI 有什么区别?
后端