保持简单

简单是一个成年人司空见惯的词,我们大部分人却觉得纯真的孩子才是简单的

很多时候,我们习惯把简单容易理解成一个意思,比如:这个问题好简单(复杂),另一层含义是:解决这个问题很容易(困难)?这个时候简单跟容易是一个意思。那假如我说:我真羡慕她能过如此简单的生活。另一层含义是什么呢?

简单设计价值观 - 图1

简单和复杂多用于形容事物或人的属性或状态,容易和困难一般形容达到某种目标的过程。生活中经常听到这样的感慨:「人活简单点真难啊!」、「系统一不小心就复杂化,非常难以维护!」。这些感慨背后流露出一种心愿 — 保持简单

对于人来说,保持简单可能意味着人情世故的简单、工作关系的简单、心态的简单。对于软件系统来说,则意味着系统设计的简单、部署运维的简单等等。

三大境界

看山是山,看水是水;看山不是山,看水不是是水;看山是山,看水是水。

保持简单的确不是一件容易的事情。禅宗提出的人生三境界中也诠释了这个理:人从简单开始,以复杂贯穿了大部分甚至整个人生,最后返璞归真。

对应到一个需求简单的软件系统中,系统的设计一开始处于简单的状态。然而软件开发的核心问题是复杂多变的业务需求,随着时间的推移,软件系统可能呈现出以下三个状态:

简单设计价值观 - 图2

没有人希望系统处于第三个状态,所有人都期望能从第二个状态回到第一个状态。映射到禅宗的人生三境界,系统的三境界应该是:

  1. 清晰 — 单一化
  2. 复杂 — 层级化
  3. 清晰 — 模块化

简单设计价值观 - 图3

在面临复杂多变的业务需求,如何设计一个恰好简单够用的系统?如何保持系统的高响应力?我们一直都没有停止对最佳实践的探索,我们始终为这些目标奋斗,只为了引导系统经历禅宗三境界。软件开发的所有问题最终都能归结到人身上,那么驱动我们不断前进的力量是什么?

我的答案之一是:对简单设计、高响应力价值的认可,对简单设计价值观的深层次内化

核心价值观

提到价值观,大家可能有一种感觉:望着这些高大上的价值观词汇,感觉缺点什么,却总又说不上来。比如Scrum的价值观:专注开放承诺勇气尊重。再比如极限编程(XP)的价值观:沟通简单反馈勇气尊重。尤其是刚开始接触这些知识体系的新人,每个词都能看懂,只是不知道它们如何去指导Scrum和XP。

我亲身经历了Scrum和XP的实践之后,再回过头来看,才深刻体会到,Scrum和XP的那些实践其实跟它们的价值观都非常吻合。同样,我能够在日常开发以及培训和练习中去落地简单设计,这背后驱使我不断前进的是已经内化的价值观:

简单设计价值观 - 图4

专注

在Scrum中,专注强调的是所有人都专注于Sprint工作和Scrum团队的目标,大家都为同一个目标努力。对于简单设计,我们要专注在哪里呢?我给大家分享我经历过三个典型的场景:

  1. 一上来匆匆忙忙编写业务代码,没有Tasking,没有测试,没有设计,业务Scope逐步偏离或扩大
  2. 在编码阶段,听到声音:“你这个设计太土气了,都没用设计模式”,于是琢磨着怎么去套设计模式
  3. 在系统架构设计阶段,有人说:“什么年代了,你还不拆出几个微服务”,于是尝试拍脑袋拆出一个分布式单体

上述三个场景根本原因是不能很好地专注于自己要实现的真实业务价值,要么缺乏思考和设计,要么受外界影响,本末倒置。你可能会质问:我们不应该多做设计来兼容后期可能出现的情况吗?为未来做设计,难免会掺入猜测,不但增加系统的复杂度,还可能浪费成本。

我们应该专注于当下的真实业务价值,专注理解业务需求,专注于刚好够用的设计,时刻让系统保持简单,尽可能创建跟业务模型匹配的代码模型。

克制

克制力是一项非常重要且需要长期培养的能力。由于受到太多外界的干扰而难以定静,成年程序员经常会因为沉浸在自己的世界里,可能出现乐观估算,以及过度设计。

而实际上,大部分乐观的估算会让团队交付面临更多风险,大部分健壮性设计会让系统难以理解和修改。我曾经面试过一个候选人,一个很简单的业务需求,他硬生生地套用了5种设计模式,叹为观止。

在日常交付项目和工作坊中,稍加留意,你可能会从开发人员嘴里听到“我觉得”、“假如”、“万一”、“以后”等用语,如果忽视了这些用语背后的念想,很可能ta正在交付一个不满足需求的软件,或者一个难以维护的系统。

程序员克制自己一个有效的方式培养业务视角,站在用户使用系统的视角尝试深刻理解业务,通过将业务需求进一步拆解成小颗粒度的任务来让自己保持聚焦。Think Big(深刻理解业务问题并拆分),Step Small(每次只聚焦在某一个小的任务),Move Fast(快速完成一个个小的任务)。

洁癖

洁癖多数场所被我们用来形容一个人在生活上不易相处,因为非常讲究个人卫生而适合一个人独自生活。我也经常在Code Review中听到同事开玩笑说我有代码洁癖,比如对命名太较真了。一开始我会有所妥协,毕竟软件开发是一个团队来完成的,如果因为我的严格而让其他人不舒适,不利于团队协作。可是时间总会告诉我,那些身贴不用心不认真或者不严格标签的小魔头在后面出来制造各种噪音,比如命名看不懂、结构不一致、架构臃肿等等。

做程序员这几年,洁癖潜移默化影响着我的编码和设计风格,小到变量命名、代码注释、文档管理,大到系统架构和部署架构,我都会时刻保持警惕,尽我所能去消除噪音污染。在没有其他不可抗拒的因素(比如客户交付压力,即便有,也应该尽力去消除)前提下,我都会尽力尝试让团队采纳我对代码洁癖的追求。

洁癖更侧重于团队个体成员,对于我们个体,可以通过不断提升自己的整洁代码、整洁架构方面的认知来强化它,并尝试在实践中去运用它们。而对于团队,我想到一条指导原则:任何有助于提升系统质量的洁癖都不应该被忽视,团队应该尽力接纳并落实。

懒惰

懒惰是一个优秀的程序员必备的特质,因为Ta勤于思考如何才能少做事情。

懒惰听起来是一个负面的词,几千年的文化价值观在告诉我们要做一个勤奋努力的人。而到软件开发领域它却成了一个靓丽的标签了,我们一起看看程序员的懒惰:

  1. 需求或设计变更,懒得改太多代码。怎么办?消除代码重复,隔离和封装变化,分离关注点
  2. 手工集成和测试,懒得反复做。怎么办?增加自动化测试并做持续集成
  3. 用户鉴权分散在各个服务中,懒得修改所有的服务。怎么办?引入API Gateway
  4. 新人上项目,搭建环境反复找我,懒得反复讲。怎么办?编写自动化脚本和文档指南

如果每次面对相同的问题,不得不花精力去处理,在这种毫无挑战的重复性工作中我们很容易犯错,所以如果你懒得去做这些事情,懒惰会驱使着你去思考一种更加高效的方式,比如集中隔离变化将其封装,引入自动化,从而取代一遍遍的重复的操作,并且你还会思考如何运用KISS(Keep it Simple and Stupid),能不出现的东西,就不要出现。

还有一类思想上懒惰的CCCV(Ctrl + C | Ctrl + V)程序员,然而,他们编码行动上一点也不懒惰,因为他们乐此不疲去重复做很多相似的代码改动。

需要勇气

抛开其他单独谈勇气意义不大,我们常说无畏之人如魔鬼,一个心中毫无畏惧的人,不受任何伦理道德和法律的束缚,便同野人无异。

在Scrum和XP中,我们要有勇气去做正确的事情、处理棘手的问题、做出承诺、坚持原则、拒绝损害工作的行为、暴露自己的不足并寻求帮助、提供有建设性的意见等。要保持简单,这些勇气都是我们不可或缺的,同时,我们要具备勇气去保持专注、克制自己、养成洁癖、滋养懒惰。