软件工程师们对社会的价值,
得益于人们认识到机器可以大幅度的减少重复劳动时间。
于是,程序员们经常通过探索多个不同场景中的相似之处,
用软件手段一次性的解决多个问题。
但是好景不长。
因为随着待覆盖的问题场景增多,
它们就变得不那么相似了,而是各有各的不同。
于是问题就来了,
我们是应该简化需求,以发挥软件的最大作用,
还是应该处理好所有细节,以满足用户的多样性需求。
这是一件值得深思的事情。
相似之处的不稳定性
提取不同事情之间的相似之处,通常有两种方式。
其一,是从具体细节上来看,它们都要做一部分相同的事情。
例如,两个页面要展示同一块内容。
其二,是从抽象层次上来看,它们要做的事情可以一概而言,
例如,两个页面都要向服务端发起请求,但具体的请求内容是不同的。
这两种提取相似性的方式,都很有效,但不完美。
我们很容易找出反例,破坏它们的稳定性,
尤其是当需要考虑的事情增多时。
这里有个常见的误区,
人们通常会认为,抽象意味着稳定,其实不是这么回事,
事实上,我们很难判断当前的抽象是否合理。
而大多数软件灾难的发生,均在于,
对可能发生的场景了解得不够深入,而过早的建立了不正确的抽象。
软件的目标用户和现有用户
值得一提的是,软件的目标用户可以和现有用户不同,
我们打算提供什么样的特性,
与现有用户期望得到什么样的特性,应该有所区分。
否则,我们永远也无法满足当前用户的所有需求,
或者即使满足了一部分用户的需求,
也难免损害另一部分用户。
因此,考虑好放弃什么,比考虑要提供什么,更重要。
软件可以不令它现有的用户全部满意,
但不可以没有自己的发展目标。
实际上,为人处世也当如此,
不论我们怎样做,都改变不了一部分人的评价。
所以,我们不能以得到更多的好评为目标。
软件也当有自身的独立品格。
软件方案的不确定性
如果从产品维度考虑问题的话,软件功能将是可取舍的,
而一旦确定了功能列表,本来我认为具体实现将是不可妥协的。
其实仍有商量的余地。
如果将自己跳出功能的实现者这个角色,
具体的实现方式,也是可以影响到上层决策的。
我在实现层面的种种考量,以及面向未来的远见和铺垫,
其实都来源于我们对软件产品的预期和判断。
因此在开发阶段早期进行不必要的优化,是危险的,
我们对问题的理解还不够深入,
很容易沉溺于自己的想象中。
其实,人们很难区分什么是自己的假设,什么是事实,
这可以认为是一个人性的弱点。
例如,拥有代码洁癖的程序员,
其实并不能证明特定的代码对别人来说也是干净的,
因此,干净的代码更好,就是一种人为假设。
我们只能说,有时候是这样,有时候又不是。
软件设计便是如此,我们根据经验所得到的一些判断,只是一种假设,而不是事实。
越笃定,往往越容易出问题。
解决问题的能力,就是为印证假设不辞劳苦的行动力。
——《思考的技术》
结语
越有经验的开发者,就越容易相信自己的经验,
软件工程师们也经常认为自己工作在确定的问题背景之中。
其实实际项目中的很多问题都是不能确定的,
各个参与者,影响了软件的最终形态,
并非是由市场这个单一因素所驱动的。
当我们意识到自己处于混沌之中的时候,
才能看清软件的真实目标,
它就像迷雾中的探险船一样,即使暂时找不到方向,也要先找一个方向前行。