You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
9.8 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 19 | 怎么避免过度设计?
俗话说,“过犹不及”。“过度”这个词仿佛会给我们一些不好的暗示。不要紧张,我们先聊一个轻松的话题。
假设有一个小地方,要建一个火车站。这个地方有数十万人口,每列火车预计上下乘客数十人,高峰时段大概近百人。你会怎么设计这个火车站?
这个火车站可能是个富丽堂皇的建筑,有宽敞的售票厅和候车室。这种设计到处可见,你可以想一想你熟悉的火车站, 也可以观察一下旅途中的火车站。
也有些火车站可能只是一个一百平米左右的小房子,只有简单的售票窗口、进站口和出站口。 比如说北京的清华园火车站,就是这样的。
也有的火车站只有标牌、售票机和遮阳棚的一小块地方,告诉人们火车在这儿停靠,就像我们常见的公交车站。
这三种火车站,都能实现旅客购票、候车、上车和下车的核心需求,帮助他们实现乘车旅行的目的。
既然乘坐火车的核心需求基本是一样的,为什么车站的差别这么大呢?
乘车旅行这个需求,衍生出了购票、候车、上车和下车的需求。
购票的需求衍生出了售票、购票、验票、检票以及各个环节排队的需求。
售票的需求衍生出了要有售票办公室和售票大厅、管理售票人员、购票人员和票贩子的需求。
售票办公室衍生出了科长办公室、科员办公室、会议室、售票窗口。售票窗口的需求也可以接着衍生出更多的需求。这个列表我们可以列很长很长,最后的结果就是火车站的建设耗资大,建设周期长,运营成本高。
哪一种火车站对旅客更方便呢?如果在一个小地方,那么第三种火车站旅客上车的环节最少,是最方便的。而且投资小,建设周期短,运营成本低。
软件开发和建火车站一样,都有设计、建设、运营和维护的环节。该怎么管理好需求和设计,是工程设计者需要重点考虑的问题。
## 避免需求膨胀
软件开发过程中,最让人痛苦的是什么?如果有这么一个调查的话,“频繁的需求变更”应该是一个高票选项。
频繁的需求变更确实让人抓狂。它变更的可不仅仅只是需求,还有不断重构的代码,不断延长的工期,不断增长的投入,以及越来越多的加班。
在一个五彩缤纷的世界里,拥有多种多样的观点,坚持不懈地改进,是一件好事情。但是,“多姿多彩”对于计算机程序而言,就是个巨大的挑战。现实世界需要丰富,而抽象程序则需要简化。这对不可避免的矛盾,就成了所有程序员的心头刺。
软件是为现实服务的,而现实总是变化的。作为程序员,我们是没有办法抵制住所有的需求变更的。为了限制无节制的需求变更,适应合理的需求进化,我们要使用两个工具,一个工具是识别最核心需求,另一个工具是迭代演进。
**识别最核心需求**
一个经济的系统,需要从小做起,而不是一上来就胡子眉毛一把抓,什么都要做。什么都要做的结果是什么都做不好。
要从小做起,最重要的就是选择。什么是必须做的?什么是现在就要做的?这是我们做选择时,要时刻准备提出和回答的两个问题。
回答这两个问题,有时候并不容易。我们知道的越多,见识越广,这两个问题越难回答。比如说开头中提到的火车站的建设。既然建造公交车站一样的火车站又方便、又省钱,为什么还要建造富丽堂皇的火车站呢?岂不是又费事又费钱?
但是,专家有他们的考量。逃票问题、安全问题、舒适问题、管理问题、就业问题等,都在他们的考虑范围内。
作为程序员,或者项目经理,我们懂得一大把的原理,学了一大把的技术,手里有一大把工具。这些技术运用起来,就是一个丰富的大世界。我们的很多需求,来源于心里的推断,而不是眼前的事实。推断产生需求,催生的系统就会形成新的事实,强化推断的演进。为了解决了不存在的问题,我们制造出真实存在的问题。
我第一次见到像公交车站一样的火车站时心里想这也算火车站吗多多少少有点震惊。我真的没有见过这么简单的火车站。有一段时间我每天都要经过这个车站也没发现什么不妥的地方。只要提前30秒到达火车站就能赶上准时出发的火车像坐公交车一样很方便。我之所以觉得它方便因为我是乘客。
如果从最终用户的眼里看软件,类似于从乘客的眼里看火车站。很多软件,承载了太多中间客户的期望和推断,最终用户的真实需求和关键需求反而被膨胀的无效需求弱化了。
所以,我们要回归到最终用户。只有从最终用户的眼里看需求,才能够识别什么是最核心的需求,什么是衍生的需求,什么是无效的需求。这样,我们才能找到一个最小的子集,那就是现在就必须满足的需求。
首先就必须满足的需求,是优先级最高的、最重要的事情,这些事情要小而精致,是我们的时间、金钱、智力投入效率最高的地方,也是回报最丰厚的地方。我们要把这些事情做到让竞争对手望尘莫及的地步。
**不要一步到位**
有一些需求很重要,但不是现在就必须做的。这就需要另外一个方法——迭代演进。第一次我们没有办法完成的事情,就放在第二次考虑。
迭代演进不仅仅需要考虑上一次没有完成的事情,还要考虑变化促生的新需求。所以,在这一步,还要像第一次一样,先找到最小的子集,也就是现在就必须满足的需求。然后,全力以赴地做好它。
这样迭代了几轮之后,一定有一些第一次看起来很重要的需求,再看反而不重要了,根本就不需要解决。
在OpenJDK社区中每年都会关闭一些有些年头的需求请求。这些需求要么没有真实用户要么已经有了替代的解决方案要么就是已经被抛弃的技术。所以一些曾经看起来值得考虑的需求时间为我们过滤掉了它们。
是不是迭代的时候,就可以考虑一些不重要的需求了呢?不,永远不要考虑不重要的需求。有时候,遏制住添加新功能、新接口的渴望,是一个困难的事情。我们需要学会放手,学会休假,以及拥有空闲时间。
管理好需求,是提高我们的工作效率以及软件效率最有效路径。但遗憾的是,我们不是总有机会决定软件需求的范围,以及优先顺序。
幸运的是,我们是产品的设计者和生产者,代码该怎么写,我们有很多话语权。
## 避免过度设计
其实和需求一样,设计也是一个容易膨胀的环节。 看看下面的漫画,是不是有些好笑又熟悉?我们只是需要一点盐,设计师会设计一个能给我们任何调味品的接口。设计接口系统会耗费很多时间,但设计师认为这会节省我们未来的时间。
![](https://static001.geekbang.org/resource/image/d5/ed/d5c799ded09527e891c92ec1d931e7ed.png)
遗憾的是,对软件来说,过度设计的接口意味着更多的代码、更多的维护、更多的修修补补,未来也不会节省我们的时间。
费迪南德·保时捷曾经说过:“一辆完美的跑车,应该首先越过终点,然后立即陷入困境。”这多少有点苛刻,但这就是“少就是多”的极简主义追求。
过度设计导致过度复杂,过度复杂导致效率降低、危险加剧、性能降低。如果保持简单而不是复杂化,大多数系统都能发挥最佳作用。这就是“少就是多”的魅力。
避免过度设计,和避免需求膨胀一样,我们要时刻准备提问和回答的两个问题:什么是必须做的?什么是现在就必须做的?
这两个问题时常提问、经常回答,有助于我们始终在用户的需求范围内思考设计,有助于我们始终关注核心问题,并且保持设计方案的简介、优雅。
## 小结
影响代码效率的最重要的两件事情,就是需求的膨胀和过度的设计。为了这两个问题,我们需要回答两个问题:
1. 什么是必须做的?
2. 什么是现在就必须做的?
弄清楚这两个问题后,我们需要做的,就是做好现在就必须做的事情。
## 一起来动手
克制住过度设计的倾向,这需要非凡的自律和自信。有时候我就想,微信的团队到底是怎么克制住自己,让微信简洁的页面保持了这么多年。那么多的诱惑,那么多流量变现的办法,都能抵制住,得要有多强大的内心和清醒的认识!
微信的聊天页面是我们最关心的信息:谁发送了信息。一对一的聊天界面,永远只使用窄窄的一行,来完成丰富的功能,红包、语音、表情包、贴图,都可以在这一行完成。所有的其他功能,比如小程序,朋友圈、合作商家,都不能干扰核心功能的呈现。现在我们看着可能觉得很简单,其实这样的设计真的很难,真的很了不起。如果不相信的话,我们来做一做练手题。
这一次的练手题我想请你思考一个银行账户管理App有哪些必须要做的事情。作为一个用户你最关心的账户管理内容是什么然后你看下常用银行的App看一看你最关心的内容需要多少步操作才可以获得也想一想哪一些内容你会毫不犹豫地删掉。
欢迎你在留言区留言,分享你的看法。也欢迎点击“请朋友读”,把这篇文章分享给你的朋友或者同事,一起交流一下。