精神不再错乱

新年刚刚结束,相信很多朋友都在不久之前许下了新年愿望——或许是要多读几本书、或许是想学习一门编程语言,又或许是其他的什么心愿。那么这其中,有多少是真正能实现的呢?

每年我都曾一遍一遍许下新年愿望,但都一遍一遍没实现过。我在重复做同样的事,却期待着不同的结果。这,就是精神错乱。

如果你还是不明白什么是精神错乱,那给你举一个我精神错乱的例子。从8年前,我就开始犯一个毛病:每隔3个月,就会得一次咽喉炎。看病时大夫告诉我:“要想不得咽喉炎,就不要吃辛辣食物。”8年前我就知道这些,但吃饭时看见有五彩缤纷的麻辣香锅、红彤彤的重庆辣子鸡和香喷喷的香辣蟹,我还是一遍一遍地吃!(那时候我还没开始吃素。)我一遍一遍地做同样的事,却在每过3个月得咽喉炎时,又一遍一遍地期望下次不得咽喉炎!精神错乱。

要想不再精神错乱,就需要做不同的事,以期获得不同的结果。

我决定做不同的事情起源于去年7月30日晚上。那天我参加大学同学聚会。依然是一遍一遍地吃绿汪汪的虎皮尖椒、金灿灿的水煮鱼里面的豆芽菜和香喷喷的香辣蟹里面的姜片儿(虽然我已经开始吃素,但我能吃肉边菜)。就这样从晚上6:30吃到了8点。这时一个老同学站起来,说他要先离开,因为要去游泳。我们说:“你明天再游呗。”他说:“我只有这么一个小爱好:每天游泳。已经坚持了4年。4年游下来体重减了20斤。将军肚没了。精神比以前好了。”

我当时就被震撼到了,竟然有人不顾香辣蟹里面香喷喷的的姜片儿而去游泳?!

我从那时起就下决心要养成每天游泳的新习惯。恰好那时为了辅导客户,我读了《习惯的力量》这本书。书里面有两个要点:

  1. 对奖励的渴望能促使你形成新习惯;
  2. 加入社区听别人的分享,能帮助你建立信仰,而不会重蹈旧习惯。

我同学离开聚会去游泳,就是一个来自社区的分享,这给了我对“游泳能够健身”的信仰,让我不会滑入不游泳的旧习惯。

信仰有了,那奖励在哪里呢?形成游泳的新习惯,需要对奖励的渴望。我想到了万能的微信朋友圈,通过在朋友圈里面晒我的游泳数据,让大家点赞来给自己鼓励。

8月7日,我这个四十多年也没游过几次泳的人,开始在广州天河游泳馆游泳。两周后买了一个Speedo的游泳手环,开始在朋友圈晒游泳数据。每天朋友圈都会有几个人给我点赞。

渐渐地,我发现除了点赞,我还获得了更多的奖励:

  • 将军肚没了,腰围从二尺九减到二尺七,这是奖励。(我度量了腰围)
  • 体重轻了,从78减到72公斤,4个月减了10多斤,这是奖励。(买了个小米体脂仪每天度量体重,出差也随身带着)
  • 体脂低了,从21%降到18%,这是奖励。(每天用体脂仪度量体脂)
  • 游泳速度快了,从8月份25分钟蛙500米,到现在能蛙1000米,这是奖励。(每天用游泳手环度量游泳距离)
  • 咽喉炎犯得少了,从今年1月18日、3月18日(还转成肺炎在家病休一周)、5月18日分别得了一次咽喉炎,到从8月7日之后到现在连续4个月没有再犯咽喉炎,这是最大的奖励。

每日度量,让我能每日看到进步或退步。把进步视作奖励。用对进步的渴望,来促使我每日游泳,控制饮食,每日度量,消灭退步,进而获得更多的奖励。

一遍一遍地做同样的事情,却一遍一遍地期望不同的结果,这就是精神错乱。要想获得不同的结果,就需要做不同的事情。加入社区,建立信仰,每日度量,每日奖励,不仅让我养成每日游泳的新习惯,相信也能帮助你我实现今后的新年愿望,精神从此不再错乱。


更多精彩洞见,请关注微信公众号:思特沃克

Share

极限编程与极限生活

【太长不读版】

ThoughtWorks团队在进行软件开发时,一般不使用Scrum和Kanban,而是使用“极限编程”(Extreme Programming)方法。“把通常的做法推进到极致”,这个来自极限编程的准则,能解决程序员在职场和生活中所面临的种种问题,并且能把其在职场和生活中的体验带到极致。

要想把事情做到极致,需要“戒贪、专注和反馈”的心态。

【完整版】

“在不同公司做技术的感受有何不同?”

“你为何搞编程道场?”

“靠技术吃饭在职场到底能走多远?”

“工程师向往的到底是什么样的文化?”

“如果职业生涯再来一遍,你会怎么规划?”

“一些企业开始‘优化’35岁以上的员工,技术人如何应对这种35岁现象的挑战?”

最近我在思考身边朋友所提出的上述问题。

回首工作过的24年,我最初从程序员开始做起,后来转为测试工程师,又转为项目经理,最后转为现在的软件开发咨询师,先后经历了4个角色。所服务的公司从国企开始,转为若干外企和私企,最后又转为现在的外企,先后经历了6家公司。

现在所从事的软件开发咨询工作,虽然不再编写大量的代码,但所涉及的内容都是与软件开发技术有关,所以还算是技术人一枚。如今,这枚技术人已经47岁,超过上面提到的35岁一轮了。

我在2016年拿到Scrum Master和PO的认证后,就去ThoughtWorks的印度办公室做ThoughtWorks University的新讲师,辅导公司新入职的应届毕业生做软件开发项目。其间我问指导我们这些新讲师的老讲师Susie Marshall:“在ThoughtWorks做开发,是否有Scrum Master?”

她说:“没有。在ThoughtWorks开发团队中,任何人都可以认领Scrum Master应做的事情。咱们更像是在做极限编程。”

极限编程是美国程序员Kent Beck在1999年提出的一种软件开发方法。它的核心理念就是“把通常的软件开发的做法推进到极致”,以便让软件开发能够达到低成本、低缺陷、高产出、高回报的效果。这也是这种方法名字中“极限”的由来。

根据24年的实践经验,我领悟到,“把通常的做法推进到极致”这条来自极限编程的准则,不仅帮助很多ThoughtWorker实现了”追求软件卓越”,比如推出了第一个持续集成工具Cruise Control,并撰写了《持续集成》这本经典之作,还能解决程序员在职场和生活中所面临的上述问题,并且能把其在职场和生活中的体验带到极致。

这种方法把什么做到极限了呢?比如,在软件开发中,测试是一个通常的做法,一般都会在程序员编写完代码后,由测试工程师来进行测试。Beck把测试这个通常的做法往前推,即在程序员编写代码前,先编写单元测试代码,然后再编写生产代码,让测试运行通过。这样就把测试推进到极致,能让程序员通过自动化单元测试更快发现自己的代码是否有功能性缺陷。

再比如,在软件开发中,代码审查也是一个通常的做法,一般会在程序员编写完代码后,由一两位资深程序员来审议代码的质量。Beck把代码审查这个做法再往前推,即在程序员编写代码前,再另外找一个程序员和他结对编程,在编写代码的过程中随时做代码审查。两人在结对编程过程中,还能互换角色,相互做代码审查。这样就把代码审查推进到极致,能让程序员在结对编程中更快地发现自己的代码是否有问题。

再比如,软件开发一般需要把一个大系统分解为若干模块,每个模块分别开发。等各个模块完成代码编写后,再做集成测试。Beck把集成测试这个做法往前推,即在编写代码的过程中,每过几小时就要进行一次自动化的集成测试,把集成测试推进到极致,能让程序员通过自动化集成测试更快地发现自己的代码是否有集成的缺陷。

“把通常的做法推进到极致”的准则,如果运用到软件开发中,就是极限编程。如果运用到日常生活中,就是极限生活。

有人会问,”这和工匠精神是不是一样?“我认为两者还是有一些差异的。工匠精神一般指把一门手艺做到精益求精、尽善尽美。其中的那门“手艺”一般不是普通人所能掌握的。比如做拉面、做辣酱、做锤子手机,普通人都做不来。而“极限生活”中的“通常的做法”,都是普通人能做的。比如上面提到的“测试”、“代码审查”和“集成测试”,普通软件开发人员都能做。下面将提到的“吃得好”和“珍惜时间”,普通人也能做到。

极限编程中所描述的种种极致的做法,能让软件开发达到低成本、低缺陷、高产出、高回报的极致效果。那么极限生活也能达到这样的极致效果吗?

根据我最近5年的亲身实践,答案是肯定的。比如,“吃得好、吃得精、活动少”所造成的营养过剩是许多人所面临的问题。身高180厘米的我5年前体重曾经达到85公斤,腰围达到二尺八。后来我把“吃得好和吃得精”向反面推进到极致,改为吃素,是那种能吃“肉边菜”的方便素,不会麻烦身边的人。5年坚持下来,体重能够控制在75公斤左右,腰围减到二尺五,同时也修炼了下面要提到的“戒贪”的心态,情绪变得更加平和。

再比如,很多人都在感慨“时间都去哪了?”,会在上下班的地铁里珍惜时间来看书。我在听了吴伯凡老师在《得到》App直播中介绍的柳比歇夫《奇特的一生》一书之后,仿效柳比歇夫,从2017年4月24日开始,每天记时间开销日记。每件事情的耗时精确到分钟,将珍惜时间推进到极致。至今两个月做下来,我知道自己在北京平均每天用在上下班的时间是两个半小时,每日平均睡眠大概是七个半小时,写这篇博客总共花了7小时40分钟。我知道每天的时间都去哪了,今后要在哪里节省时间。这种珍惜时间的极致体验让我感觉活得很踏实。

要想做到“把通常的做法推进到极致”,需要下面的心态。

戒贪

贪心会耗散你宝贵的注意力,让你分辨不出哪个通常的做法值得被推进到极致。比如我20多年前在国营单位做IT人员的时候,虽然早已发现这个单位并不适合我的个人发展,但是当时贪图国营单位的稳定,在这个单位纠结了7年多才提出辞职。那时一个人如果从国营单位辞职就会被称为“下海”。我在下海前这7年多的时间里,在贪图安逸的心态下,从没有将哪个通常的做法推进到极致,导致下海后一无所长,很长一段时间难以找到称心的工作。

专注

没有了贪心,就能静下心来发现自己的一个喜好和优势。然后在这个点上专注下去,把它做到极致,实现单点突破。比如,我在3年前用裸辞来戒贪,决定要找到一件值得专注的事情。在读书的过程中,我发现“编程操练”是程序员刻意练习编程的好办法。于是就专注于这个点,把这种做法向前推进到极致。我找到一些愿意免费提供场地的公司,办了30多次免费的线下“编程道场”活动。这些经历让我通过编程掌握了不少设计模式和测试驱动开发方法,促使我完成了《驯服烂代码》的写作并出版,并在编程道场中结识了不少好友,有些好友成为了我软件开发咨询的客户。戒贪之后的专注,令我有机会将编程道场做到了极致。

反馈

在“把通常的做法推进到极致”的过程中,你的做法并不一定都是正确的。需要不断收集反馈,并持续调整。比如我最初在撰写《驯服烂代码》的第一章时,使用了类似几何学的逻辑推导的方法来论述测试驱动方法的有效性。将草稿发给机械工业出版社的杨福川老师审阅后,得到了“难以阅读”的反馈。这个反馈促使我开始思考如何才能以吸引读者的方式来组织该书内容。

我受上面提到的编程道场匠友们的反馈的启发,最后把书的内容演进成写两位程序员用结对编程的方式来进行编程操练。该书出版两年后,得知参加编程道场的中国矿业大学的刘凯欣同学把编程操练推荐给了她的朱老师,并促成学校开始了敏捷软件开发的课程,这令我大为欣喜。上面所说的这些反馈,都帮助我将写书做到极致。

“把通常的做法推进到极致”,用在软件开发中,就是极限编程。用在生活中,就是极限生活。现在看看本文开头的那些问题是否能用极限编程和极限生活来解决。

“在不同公司做技术的感受有何不同?”

我如今在ThoughtWorks公司做技术,能够实现“把通常的做法推进到极致”,比如测试先行、持续集成和结对编程,这是一种极致的体验,是最大的福利。我以前所在的其他公司,都没有这个福利。

“你为何搞编程道场?”

开始是为了写书。现在想来,是在实践”极限生活“。

“工程师向往的到底是什么样的文化?”

我向往极限编程和极限生活的文化。

“如果职业生涯再来一遍,你怎么规划?”

首先建立“戒贪、专注和反馈”的心态,然后持续地做出“把通常的做法推进到极致”的职业规划。

“一些企业开始‘优化’35岁以上的员工,技术人如何应对这种35岁现象的挑战?”“靠技术吃饭在职场到底能走多远?”

我多年的实践表明,只要你能把一个乃至若干个通常的技术做法推进到极致,并能给企业带来价值,那么无论你是多大年纪,你已经获得了职场的主动权。


更多精彩内容,请关注微信公众号:软件乌托邦

Share

走进神秘的ThoughtWorks咨询团队

成立五年的ThoughtWorks咨询团队,在外人眼中,甚至在ThoughtWorks内部其他团队眼中,一直是一支神秘的队伍。

图:部分咨询团队成员   摄影师:张硕(ThoughtWorks咨询师,左上角拿相机者)

神秘

为什么神秘呢?一方面,在ThoughtWorks只有中国区有独立做咨询的团队,因此这支团队对于中国区以外的ThoughtWorker来说很神秘;另一方面,这支团队的工作方式相对独立,与其他团队联系较少。

可能有读者不大清楚什么是咨询工作。ThoughtWorks中国区所提供的专业服务大致分为两种,一种是交付,另一种是咨询。前者是指ThoughtWorks开发团队直接为客户开发软件,后者则是ThoughtWorks咨询师辅导客户的团队来更好地开发软件。

交付工作的完成,需要各个工种的配合,所以团队人数会较多,每个团队大概会有七八个人。而咨询工作不同,好比你通常不会请三位以上的健身教练同时辅导你一样,客户一般只安排一位教练(或两位教练结对)来辅导一个团队。在这种情况下,咨询团队这30多人,工作时会分散到全国各地的客户团队中,彼此相对独立地工作。

咨询师相互之间,除了结对工作之外,只有在团队例会上,才能了解其他咨询师的工作情况。连咨询师都不甚了解本团队其他队友的工作情况,更何况外界呢?再加上咨询师常年出差,奔波在客户现场,很少有时间去办公室做分享,这就让这支团队更加神秘。

三种咨询师

这支神秘的团队,有三种咨询师。

第一种:管理咨询师

这些咨询师有些会深入到客户基层开发团队,来辅导客户团队进行Scrum迭代开发和看板实践;有些会辅导客户的业务分析人员做设计思维工作坊、拆分用户故事、编写验收条件;有些会运用ThoughtWorks的精益企业理念和EDGE投资组合管理框架,来辅导客户公司总裁制定组织级敏捷转型的决策。

第二种:技术咨询师

他们中有些会评估客户现有软件系统的架构,并提出改进建议;有些会辅导客户程序员编写测试代码和进行代码重构;有些会辅导客户的持续集成工程师搭建部署流水线;有些会辅导客户构建微服务架构的系统;有些会开始探索VR/AR(虚拟现实/增强现实)、区块链技术、AI(人工智能)、自动驾驶汽车和无服务器架构等前沿“黑科技”。

第三种:全栈咨询师

这些咨询师能一人兼作上述两种工作,这也是笔者所向往的。换句话说,这种咨询师:既能和总裁聊天,又能辅导Scrum和看板;既能引入极限编程,又能指导需求管理;既能改进持续集成,又能和程序员结对写单元测试;既能编制咨询项目计划,又能给团队做培训;既会设计思维,又能干点售前。要想修炼成全栈咨询师,用同事大魔头(杨云)的话说,需要“胆子大,学得快,讲得棒。”其中,“学得快”是核心。

套路

这三种咨询师在辅导一个新团队做敏捷转型时,常用的套路是有共性的。大概可以分为四步:

  • 第一步:评估。根据客户团队情况,使用ThoughtWorks所总结的各种成熟度模型(比如敏捷成熟度模型和持续交付成熟度模型),来对客户团队的技术和管理实践进行评估,找出痛点和改进点。
  • 第二步:培训。给客户团队进行Scrum和看板、用户故事、持续交付等转型相关内容的培训,熟悉客户团队成员,发现客户团队中做敏捷转型的忠实粉丝,并让团队对转型中要做的工作获得统一认识。
  • 第三步:辅导。与客户团队成员结对工作,来一对一或一对多地辅导Scrum迭代开发和看板实践、用户故事拆分及其验收条件编写、编写自动化测试、搭建部署流水线等等。

第四步:回顾。一段时间后,让团队回顾转型取得的成绩,并找出下一步持续改进的目标。

优势

如果你读到这里,相信这支团队在你面前已经不再那么神秘了。笔者掐指一算,到今天已经加入ThoughtWorks快两年半了。以前神秘的团队,如今已成为笔者在深夜提笔撰写此文的动力。那么这支ThoughtWorks咨询团队,与其他竞争对手相比究竟有何优势呢?笔者觉得至少有两点优势:

  • 第一,技术能落地。ThoughtWorks最大的优势就是工程技术实践及分享的能力,比如代码重构和首席科学家Martin Fowler的《重构》一书、持续交付和Jez Humble及Dave Farley的同名书、微服务及Martin Fowler的同名博客等等。而那些来自工程实践一线的咨询师们,能令咨询方案落到实处。这一点,是很多竞争对手难以做到的。
  • 第二,锦囊妙计多。ThoughtWorks中国区总经理张松曾经对笔者说过,ThoughtWorks与其他竞争对手最大的不同,就是公司人数众多。而这支神秘团队的领袖孔雀然(肖然)曾经说,在ThoughtWorks最大的好处,就是能利用上面所提到的Hivemind。综合起来,这些通过了最难面试的ThoughtWorkers聚集了为数众多的力量,又形成的强大的Hivemind,能让你在遇事不决时,助你拥有足够多的锦囊妙计。相比笔者曾经从事过的只有一人的自由咨询师或仅有几人的小咨询公司来说,你能从几千位ThoughtWorkers那里获得更多的智慧,让你进步得更快。

加入

有朋友发消息说:“一直非常向往,待我能力到位了,一定努力尝试”。下文也将谈到ThoughtWorks面试难的问题。其实面试ThoughtWorks咨询师是有攻略的。根据笔者两年前加入ThoughtWorks的经验,做好下面几点面试攻略,能极大地提高你的成功率:

  1. PREP回答法。在回答ThoughtWorks的面试问题时,一定要紧扣问题,不要跑题。可以采用笔者从toastmasters.org的Table Topics环节所习得的即兴演讲技巧——PREP (Point-Reason-Example-Point),即先根据面试问题简短阐述你的观点,然后说明原因,接着举一个实例来说明,最后总结一下你的观点。
  2. 刻意练习硬技能。如果你想尝试技术咨询师,可以看Coding Dojo Handbook 或笔者的《驯服烂代码》,然后去cyber-dojo.org上练习TDD;如果你想尝试管理咨询师,可以参考“读书雷达”,读其中相关的书籍,并发表博客来分享你的收获。
  3. 社区平台多分享。如果你想尝试技术咨询师,要多在github上分享你的代码。如果你想尝试管理咨询师,要多在TiD这样的技术大会上作演讲,多写管理相关的博客。

最后再强调一点:你不必等什么都精通了再来尝试ThoughtWorks咨询师;只要你能够“学得快”就行。


更多精彩洞见,请关注微信公众号:思特沃克

Share

实例化DevOps原则

【摘要】

  • DevOps原则所追求的愿景,就是“让业务所要求的那些变化能随时上线可用”;
  • DevOps的起源表明,其原则是从Agile与Lean的实践当中提炼而来,因此与Agile和Lean的原则并无二致;
  • 本文所讨论的DevOps原则可以用“人、产品、流程和工具”这4个维度来进行组织。

【正文】

“你在做用户故事拆分?这不是在做DevOps。”这是笔者在2016年以咨询师的身份,参与一家大型跨国金融企业的Agile和DevOps转型时所听到的话。在这家企业,Agile和DevOps明显指的是不同的东西:前者专指每日站会、计划会、回顾会等Scrum的实践和用户故事实践;后者专指自动化、工具链和基础设施等实践。过了一段时间,笔者把本文所列举的一些DevOps原则发到一个相关微信群里面,得到了这样的反馈:“怎么满眼都是敏捷和精益?”“感觉DevOps被一群不操作Op的人给玩儿坏了。”

这些经历让笔者开始关心这些问题:既然Dev指的是“开发”,Ops指的是“运维”,那么到底什么是DevOps?它的原则是什么?它和敏捷、精益的关系是什么?让我们先观察一下DevOps的起源[1][2]

DevOps的起源可以分为两条线

第一条线是:比利时独立咨询师Patrick Debois

2007年他在比利以咨询师的身份,参与了一个政府数据中心迁移中的测试工作。他在做测试时,需要频繁往返于Dev团队和Ops团队之间。Dev团队已经实践了敏捷,而Ops团队还是传统运维的工作方式。看到Ops团队每天忙于救火和疲于奔命的状态,他在想:能否把敏捷的实践引入Ops团队呢?

第二条线是:当时雅虎旗下的图片分享网站Flickr

这家公司的运维部门经理John Allspaw和工程师Paul Hammond,于2009年6月23日在美国圣荷西举办的Velocity 2009大会上,发表了一个引燃DevOps的演讲。这个演讲的题目在当时很抢眼--《每天部署10次以上:Flickr公司的Dev与Ops的合作》[3]

这个演讲有一个核心议题:Dev和Ops的目标到底是不是冲突?传统观念认为Dev和Ops的目标是有冲突的——Dev的工作是添加新特性,而Ops的工作是保持系统运行的稳定和快速;而Dev在添加新特性时所带来的代码变化,会导致系统运行不稳定和变慢,从而引发Dev与Ops的冲突。然而从全局来看,Dev和Ops的目标是一致的,即都是“让业务所要求的那些变化能随时上线可用”。

这样抢眼的题目和鲜明的观点,自然抓住了当时还在比利时的Debois。他在“推特”上发帖:“可惜没法去现场参加。”朋友Paul Nasrat回帖说:“为什么不在比利时搞一个你自己的Velocity大会?”这两条线使得Debois撸起袖子,于2009年10月30至31日,在比利时的第二大城市根特,以社区自发的形式举办了一个名为DevOpsDays的大会。这次大会吸引了不少开发者、系统管理员和软件工具程序员。这两天大家聊得太开心了,会议结束还不过瘾,回去继续在“推特”上聊。限于推特140个字符的制约,Debois把DevOpsDays中的Days去掉,而创建了#DevOps#这个“推特”聊天主题标签,DevOps诞生了。

Flickr公司的两位演讲者所表达的“Dev和Ops的共同目标是让业务所要求的那些变化能随时上线可用”这一观点,其实就是DevOps的愿景。而要达到这一点,可以使用一个现成的工具:精益。源自丰田生产方式的“精益”的愿景就是“Shortest lead time”,即用最短的时间来完成从客户下订单到收到货物的全过程。这恰好能帮助实现DevOps的上述愿景。《持续交付》的作者之一Jez Humble也体会出精益在DevOps中的重要性,以至于他把DevOps的CAMS框架修订为CALMS[4],其中增加的L指的就是Lean(精益),这一点下文还会提及。

从上面DevOps的起源中能够看出三点:

  1. DevOps源自草根社区,最初并没有什么自上而下设计出来的理论框架;
  2. DevOps背后的原则,就是上面两条线中所涉及的敏捷和精益的原则;
  3. DevOps的愿景是让业务所要求的那些变化能随时上线可用。

一旦了解了上面第2点,就不会有前文中所说的“Agile和DevOps是不同的东西”和“感觉DevOps被一群不操作Op的人给玩儿坏了”这样的说法。

因为DevOps源自草根,没有什么框架,所以如何定义DevOps成了DevOps社区里面的一个大难题[5]。一些DevOps从业者,纷纷设定自己的DevOps框架。其中比较有名的框架有上文提到的Damon Edwards所定义并被Jez Humble所修订的CALMS,和Gene Kim所定义的The Three Ways[6]

CALMS:

  • Culture – 文化:公司各个角色一起担当业务变化,实现有效协作和沟通;
  • Automation – 自动化:在价值链中尽量除去手工步骤;
  • Lean – 精益:运用精益原则更频繁地交付价值;
  • Metrics – 度量:度量并使用数据来优化交付周期;
  • Sharing – 分享:分享成功和失败的经验来相互学习。

The Three Ways:

  • The First Way: System Thinking (系统思考:强调全局优化,避免局部优化);
  • The Second Way: Amplify Feedback Loops (经过放大的反馈回路:创建从开发过程下游至上游的反馈环);
  • The Third Way: Culture of Continual Experimentation And Learning(持续做试验和学习的文化:持续做试验,承担风险、从失败中学习;通过反复实践来达到精通)。

(图片来自:http://t.cn/RijRjYS)

本文试着从“人、产品、流程和工具”4个维度,来梳理DevOps的一些原则。为什么会有这4个维度?

先看前三个维度:“人”、“产品”和“流程”。在一百多年前的工业经济时代,由于物质匮乏,所以当时占主导地位的泰勒科学管理理论将“流程”这个维度放到了第一位,让企业首先通过标准化的“流程”达到规模化的制造能力,来满足供不应求的市场。市场上可购买的商品少,人们对“产品”的质量、设计也就不介意了,所以“产品”排在了第二位。而标准化的流程把工人的素质标准降到了最低,只要带着一双手来,在流水线上重复一个动作就好了,不需要动脑子,因此“人”排在了最后的位置。

一百年后,工业经济霸主的地位已被知识经济所取代。在具有知识密集特点的敏捷软件开发的上下文中,这三个维度的顺序颠倒了:“人”的优先级最高,因为只有依靠“人”的创造力才能应对多变的业务需求;给用户提供价值的“产品”依旧排第二位,因为这是企业赖以生存的根基;而“流程”可以为了“人”来高效地实现“产品”而进行定制,所以优先级最低。而强调自动化的DevOps离不开好用的“工具”,“工具”又可以依据流程来定制,因而可以补在“流程”的后面。

(图片来自:http://t.cn/RijRMrp)

下面所描述的DevOps原则,来源于敏捷、精益和DevOps的一些具体实践。虽然没有涵盖DevOps的所有实践,但已经包括笔者最近一年在DevOps的实践中所感悟的主要内容,而且今后会继续完善。

一般的文章对于“原则”的阐述都比较抽象,有点像上面提到的CALMS和The Three Ways这两个框架的定义方式那样——仅仅把几个名词或短语放到那里。对于不熟悉Agile、Lean和DevOps的人来说,看了上述框架还是不知道DevOps到底是做啥的。

为了让DevOps原则的描述更加具体生动,笔者参考敏捷宣言的写法和实例化需求的做法(即用具体的实际例子来编写验收条件),使用了“高于”和“而非”的句式来对比两个具体实践的实例,且尽量用一些具体的实践来代表相应的原则,如“部署流水线”等。其中,“高于”表示右边的实践虽然不如左边的好,但还是有价值的。“而非”表示右边的实践并不值得推荐。这就是本文标题中“实例化”的由来。

1. 人

领导者身体力行持续改进 高于 关注工具和基础设施

很多企业(包括笔者所辅导的企业)都在实践DevOps。要想让DevOps这颗树苗茁壮成长,企业要为其提供一个良好的土壤——即企业文化。而企业文化,是企业领导者引导塑造的。DevOps对于国内大部分企业来说,都是一个前所未有的新事物。必须通过不断做试验,才能找到培育它生长的土壤方,做试验就是为持续改进做准备。笔者所辅导的企业,工程师被项目进度压得喘不过气来,根本没有时间学习新工具和新方法,更别提做试验了。

(图片来自:http://www.yes123.com.tw/)

所以只有领导者身体力行,不仅自己亲自做试验和进行持续改进,并给工程师足够的时间来做试验和持续改进,这样所创造出良好的环境,才能让那些自动化工具和基础设施在企业内部得到有效利用。

试验并改进流程 而非 指责人的过失

丰田公司有一句口号:“对流程苛,对人员柔”,意思是说:每位员工都会尽力做好工作的,那些在工作中所出现的问题都是流程的问题。因为根据这种有问题的流程来工作,无论是谁都会出同样的问题。前面说过,DevOps对于国内大部分企业都是新事物,需要做试验来“摸着石头过河”,做试验就有失败的时候,此时就要调整流程,而不是怪罪于人,否则企业没有人会去继续尝试DevOps。

产品思维 高于 项目思维

根据这一个原则可以定义“人”的组织结构——团队结构,即可以按照产品而不是项目来组建团队。这样的产品团队包括了Dev、Ops、BA、Tester、PO和Architect等各种角色,他们相互配合且不依靠团队以外的其他角色就能独立自主地交付软件产品,这个产品团队负责该产品从生到死的全生命周期,并且只要产品还在,这个团队就不会解散。这种设置会让团队的不同角色目标一致,比起从目标不一致的各种职能团队(比如Dev团队、Tester团队和BA团队)抽调人员拼凑成临时的项目团队,磨合期更短,更加有战斗力。

2. 产品

质量和安全内建 而非 晚期度量和检查

产品需要质量和安全来保证价值。人们长期认为“高质量”意味着“高成本”,因为要维护高质量,需要在产品出厂前做大批量检测,并销毁那些次品,这就花费了高昂的成本。但丰田公司却说“高质量是免费的”[7]。这是怎么做到的呢?这其实就是前文提到的丰田公司“对流程苛”的结果。丰田公司通过持续改进流程,“一次就根据最佳流程或实践把事情做对,并持续改进这些流程和实践,使其一直保持最佳”,这样就能在脱离后期大规模检查的情况下保证高质量,同时其成本也趋近于零。

客户反馈 高于 按期交付

产品是否实现了价值,只有通过客户的反馈才能知道。很多团队往往过分关注交付期限,而忽视客户反馈。这样做的后果,就是虽然按期交付,但是产品却不是客户所期望的,造成返工或项目失败。

基于不可变容器的微服务 高于 单块应用

产品需要能快速地开发、测试和部署才能有效地交付价值。对于复杂度高的大型产品,如果可以由多个微服务组合而成,每个微服务都能独立地开发、测试、部署和上线。这比起必须集成各个模块才能进行手工测试的单块应用来说,更能实现各个微服务之间的并行研发,加快每个微服务的开发下游至上游的反馈环的反馈速度,进而缩短项目进度,让价值交付得更快。不可变容器指的是软件产品被封装到一个类似docker这样的容器内上线,且上线后不可手工修改其配置。如果一定要修改,也只能通过部署流水线把要修改的内容重新打包成另一个新的不可变容器来上线。这样做的好处是能够实现部署和发布自动化以及进行更好的版本控制,消除线上手工配置所带来的无法审计的风险。这一实践是本文写作时期的推荐实践,该实践今后还会继续演进。

3. 流程

管理层实践Improvement Kata和Coaching Kata进行流程持续改进 高于 用结果导向进行管理

佛家说:“菩萨畏因,众生畏果”。传统按结果导向进行管理的一个弊病,就是团队成员会把注意力放到结果上,而不是产生这样结果的原因——即过程改进之上。这样的后果就是,大家会把精力放到如何让报表好看,而不是真正地提高团队成员的持续改进能力来真正达到所期望的结果。企业管理层可以参考《丰田套路》[8]一书来带头实践Improvement Kata和Coaching Kata,让企业产生持续改进的文化。其中,Improvement Kata是通过一系列“确定目标—>考察现状—>识别困难—>制定方案—>观察成效”的PDCA反馈环来做持续改进;Coaching Kata是通过导师“一对一带学徒”的方式来让企业全员掌握持续改进的方法。

全局优化 而非 局部优化

由于大部分按职能组织团队的企业内部都存在部门割据的问题,导致大家都在做本职能部门内的局部优化,而没人做部门间的整体优化。有些部门间的扯皮时间甚至长达数月,严重影响了产品的交付。这提醒我们,全局优化来提高企业整体竞争力,才是各个部门赖以生存的保障。

单件流 高于 库存

单件流指的是,正在制作的产品的各个模块,能从最初的对其增加价值的加工步骤,直接传递到下一个增值加工步骤进行加工,并最终被传递到客户手中,在这个过程中,各个步骤之间没有发生等待或者排队的现象。而如果在各个步骤的传递过程中发生了等待或排队,那就等同于建立了库存。

软件开发中常见的库存包括排队等候开发的需求、排队等候测试的代码、排队等待修复的缺陷和排队等待上线的产品特性;隐藏很深的库存可能由诸如那些有固定期限(比如每月一次)的“用户验收测试”的流程造成——月初几天就开发测试完毕的产品特性必须要被存放近一个月,等到月底“用户验收测试”后才能继续往下游走。软件开发中的上述库存就是让项目延期的最大原因。而企业如果能做到单件流,那么就相当于消灭了库存,让价值在不同环节之间流动得最快,进而实现了前文所提到的全局优化。

4. 工具

自动化 高于 手工

按照固定流程所进行的手工工作,比如手工回归测试和手工部署工作,无趣、缓慢且无法审计。如果能将其代码化,且用版本控制系统管理起来,并加以自动化,这既能节省以后手工运行的大量时间,又能体验到开发测试和部署脚本工作的乐趣。

基础设施及代码 高于 手工配置

传统Ops的部署工作有些需要用鼠标在界面上点来点去,效率很低;效率高一些的Ops用了自动化脚本,但很多脚本都没有进行版本控制,更别提针对脚本的自动化测试了。 如果能够将基础设施的维护工作都通过编写代码并加以版本控制来完成,那么会带来很多好处,比如Ops可以不用通过访问生产环境,就能知道生产环境上的配置情况;非运维人员如Dev,就有机会去学习这些运维配置代码并且加以修改,提升整个团队的DevOps能力;另外工具能方便地读取这些代码,来自动化地维护基层设施,大幅度提升Ops的工作效率。

部署流水线 而非 每日构建

程序员每天都会用代码提交来为软件系统增加价值。而如何有效地保证每次提交的代码质量过关而不会有损现有系统的价值呢?这就需要一个代码构建系统自动地验证代码在编译、测试和打包等工作的过程中,是否符合质量要求。有些团队还在每晚做一次代码构建,这个昔日的“最佳”实践如今已经不再被推荐。一个团队程序员们每天代码的提交会有很多,如果晚上构建发现了错误,第二天从这些众多提交中发现谁导致的错误,将是一个很困难的事情。推荐的做法是每一次代码提交,都能自动触发部署流水线来检查该提交是否通过了自动化单元、验收和性能等测试。一旦发现问题,就能轻松定位是谁在哪个环节出现了什么问题。

总结

DevOps的原则来自从业者们在日常工作中运用敏捷、精益原则的具体实践。这些原则可以按照“人、产品、流程和工具”4个维度来组织。这些原则和实践的目的,都是要实现DevOps的愿景——让业务所要求的那些变化能随时上线可用。

下图是本文实例化DevOps原则的一个可视化总结。

感谢笔者在ThoughtWorks的同事Patrick B. Sarnacke、顾宇、马博文、黄博文、蔡同、万金、张凯峰、周文晔和亢江妹。他们在阅读了初稿后,给笔者提出了精彩的反馈,使得本文得以改进。

后记:

在本文所讨论的上下文中,原则(Principle)指的是主观的“影响行为的坚定信念”(a moral rule or a strong belief that influences your actions),而不是客观的”自然法则“(a general or scientific law that explains how sth works or why sth happens)。括号中的英文来自《牛津高阶英语词典》第8版对Principle一词的解释。所以本文所讨论的“原则(Principles)”和“价值观(Values, beliefs about what is right and wrong and what is important in life)”这两个概念在内涵上是一致的,都是主观的。

在本文发布前的ThoughtWorks内部审阅期间,笔者的同事顾宇就已经提出了同样的问题,“我看到‘高于’就想到敏捷宣言,敏捷宣言是个价值观,就是对价值的取舍。能否把本文改叫DevOps价值观?” 我当时查到了一篇文章《What is the difference between a value and a principle?》,得到的结论是“Principles是客观的,比如重力这样的自然法则;而Values是主观的”。于是就着手开始把文中的“原则(Principle)”改为“价值观(Value)”。但是改到一半时,发现人们也会说“精益的原则”(PRINCIPLES OF LEAN),而一般不说“精益的价值观”(The values of Lean)。于是再查《牛津高阶英语词典》,发现Principle这个词有上述主观和客观的两个含义。于是就决定使用Principle的主观的含义。

注:

[1] The (Short) History of DevOps, https://www.youtube.com/watch?v=o7-IuYS0iSE

[2] #DevOps的前世今生# 1. DevOps编年史, http://www.jianshu.com/p/f40209023006

[3] 10+ Deploys Per Day: Dev and Ops Cooperation at Flickr, https://www.slideshare.net/jallspaw/10-deploys-per-day-dev-and-ops-cooperation-at-flickr, https://www.youtube.com/watch?v=LdOe18KhtT4

[4] Quantifying DevOps Capability: It’s Important To Keep CALMS, https://blog.rackspace.com/quantifying-devops-capability-its-important-to-keep-calms

[5] THE PROBLEM WITH DEFINING DEVOPS, https://www.upguard.com/blog/the-problem-with-defining-devops

[6] The Three Ways: The Principles Underpinning DevOps, http://itrevolution.com/the-three-ways-principles-underpinning-devops/

[7] 【冬吴相对论】144丰田之殇(下), http://blog.sina.com.cn/s/blog_7a25b1b00102ws84.html

[8] 丰田套路,https://read.douban.com/ebook/10138727/


更多精彩洞见,请关注微信公众号:思特沃克

Share

从“四色建模法”到“限界纸笔建模法”

对于领域专家、程序员和测试工程师来说,领域建模所构建的概念模型是撑起软件开发系统的骨架。领域建模的方法有很多种,ThoughtWorks的同事们经常使用经过徐昊改编的“四色建模法”[1]来进行建模。而本文所描述的“限界纸笔建模法”,在“四色建模法”的“时标对象”的基础上确定”限界上下文”[2]与“聚集”[3]的概念,再使用“纸和笔来管理”的方法,力图在建模过程中实现“分而治之”,增强数据的完整性,并避免过度设计。

为了便于说明,下文将以“小画笔”绘画课外班的业务为例,首先描述同事亢江妹用四色建模法对其所建的模型,然后再描述如何在其“时标对象”的基础上,运用限界纸笔建模法进行建模。

“小画笔”绘画课外班

“小画笔”是一家面向2-10岁小朋友的绘画培训机构。乐乐老师是这个培训机构的主管。她毕业于北京师范学院,有一些认识的同学和老师愿意在业余时间授课来获得一定收入。

“小画笔”目前有三个班:

  • 美术预科:适合2-3岁孩子,从看、摸、闻、听、尝培养艺术感;每期课程8次,每周一次,周末上;每班最少6个孩子开课,最多10个孩子。
  • 书法:适合3-6岁孩子,学习字体结构、笔画线条;每期课程8次,每周一次,周末或晚上上; 每班最少6个孩子开课,最多12个孩子。
  • 儿童绘本:适合年龄5-10岁,用文字和图画表达;每期课程8次,每周一次,周末或晚上上; 每班最少6个孩子开课,最多12个孩子。

“小画笔”有三个教室:达芬奇,毕加索和梵高。

每两个月开始新期课程,8次课结束后重新开始。

乐乐老师的主要工作是:

  • 根据现有老师能够讲授的课程及时间,做好课程表安排,提前两个月把下期课程介绍做好,印成宣传彩页;
  • 在附近社区里给家长宣传,招募生源;
  • 接受家长报名(电话或面对面),记录和追踪报名情况;
  • 收取学费,学费支付采用现金付款,或银联卡刷卡支付;
  • 争取在每一期课程开始前都有足够学员报名,可以准时开班;
  • 保证课程质量和安全,保证营收,维持培训机构正常运转。

乐乐老师需要处理的三个核心问题有:

  • 下一期的课程如何安排? – 排课
  • 如何招生和管理报名? – 管理报名
  • 如何保证课程质量? – 管理课堂

挑战:

请为乐乐老师设计一个软件工具的概念模型,能让乐乐老师方便地管理排课、报名和学员考勤,维护“小画笔”的正常运营。

在日常运营中,乐乐老师经常碰到下列问题:

  • 课程开始后发现有孩子没来上课,也没有请假,需要查找家长联系电话来询问。
  • 有时孩子请假会造成缺课,家长会要求在后期课程中补上。乐乐老师需要记录孩子的上课次数,在可以补上课程的时候通知孩子来参加。
  • 需要查看还有哪个家长没有缴费,通知他们缴费。
  • 需要查看某个孩子的缴费记录,以确认家长是否缴费。
  • 经常有家长要求先试一次课,再确定报名交钱。但每班只能在报名不满额的情况下才能试听,且最多只能允许3个孩子试听。所以乐乐需要追踪每班报名多少孩子、试学多少孩子、还有没有试学名额。
  • 需要经常查看每班是否报满,可否开课;如果不满,需要再去小区做宣传。
  • 需要提前跟上课老师确认,确保他们能按时授课。
  • 有些课程可能会有一位主任老师和另一位见习老师来共同授课,所以这些课程每门课需要管理多位老师的信息。
  • 需要跟踪教学质量,确保老师按时按质授课,及正常教学安全和秩序;

请检查你所设计的概念模型能否帮乐乐老师解决上述问题。

用“四色建模法”进行建模

第一步:寻找要追溯的事件

1. 谁,在什么时候,为谁,报名了什么课程

2. 谁,在什么时候,为谁,支付了多少学费

3. 谁,在什么时候,上了什么课程

第二步:识别“时标对象”[4]

按时间发展的先后顺序,用红色所表示的起到“追溯单据”作用的“时标”概念,如下图所示:

 

1

 

第三步:寻找时标对象周围的“人、地、物”[5]

在“时标”对象周围的用绿色所表示的“人、地、物”概念,如下图所示:

2

 

第四步:抽象“角色”[6]

在上图中插入用黄色所表示的“角色”概念,如下图所示:

3

 

第五步:补充“描述”信息[7]

在上图中插入用蓝色所表示的“描述”概念,如下图所示:

4

 

用“限界纸笔建模法”进行建模

上面用四色建模法对“小画笔”绘画课外班的软件系统所做的建模过程,最大的亮点是按时间发展的先后顺序,识别出起到“追溯单据”作用的“时标”概念。这种识别方法直达业务核心数据,简便有效。

此外,限界纸笔建模法可以继续进行以下三项建模工作:

1. 划分限界上下文,避免模型发展成“大泥球架构”。

2. 强调“聚集根”[8]的概念,更好地保证数据的完整性。

3. 寻找“恰好够用”的概念,避免过度设计,降低所建模型的复杂性。

一个“聚集根”好比一个经理,这个“聚集”所汇聚的所有彼此相关的概念好比这个经理手下管理的所有员工。当另一个“聚集”的经理,要访问该“聚集”中的某个员工时,必须要通过该“聚集”的“聚集根”这个经理的同意和安排才行,不能直接去找。这样设计能够将管理数据的访问职责缩小到一些“经理”那里,既方便定位职责,也有助于增强数据的完整性。

下面尝试用限界纸笔建模法来对“小画笔”绘画课外班的软件系统建模。

第一步:根据“追溯单据”的价值识别核心领域[9]

首先以“小画笔”绘画课外班的业务“追溯单据”为线索,列出这些追溯单据为乐乐老师所提供价值,并合并其中一些价值相同的单据。比如对于一个只有三间教室的小课外培训机构,只有交费成功的“报名”才视作有效报名。所以“报名登记表”和“交费纪录”可以合并。然后确定这些价值所对应的核心领域。如下表所示:

5

 

第二步:确定核心领域之间的依赖关系

排课、报名与签到三个核心领域的依赖关系如下所示:

排课 <—— 报名 <—— 签到

上面的箭头表示:“报名”需要依赖“排课”所提供的信息,而“签到”需要依赖“报名”所提供的信息。

第三步:用纸和笔画表格并写实例

先选择一个核心领域,然后开始在其所对应的“限界上下文”中,开始对其建模。假设时光回退100年,那时没有电脑,只有纸和笔。用纸和笔画表格并写实例的方法,来管理该核心领域的“恰好够用”的数据,来达成乐乐老师在此核心领域所期望的价值。

首先选择“排课”。下图是用纸和笔画出的表格,并有一条实例数据:

6

 

第四步:确定“聚集根”

给表中所有的列找一个“经理”来作为“聚集根”。这里选择“课程”作为“聚集根”,它是一种具有唯一标识(即有唯一的课程编号)的Entity[10]概念,然后把表中所有的列名都抄写到表下“聚集根”的右侧,并用括号括起来,如下图所示:

7

 

第五步:以“人以群分”的原则抽取新的“聚集”

观察所抄写的“聚集根”右侧所有聚集在一起的各个概念,提取出总是“一起玩儿”的多个概念,形成一个新的聚集,并确定这个新聚集的名字。比如,“上课时间”、“起始日期”、“次数”这三个概念总是一起出现,它们决定了这门课程的学时,所以就提取“学时”这个新聚集,并把这三个概念从“课程”右侧划掉。“学时”这个概念不需要有唯一标识,所以是Value Object[11]概念。它和“课程”是一对一的关系。用相同的方法可以提取“老师”这个新聚集,它是Entity概念,“课程”与它是一对多的关系。如下图所示:

8

 

对于那些只“自己单独玩儿”的概念,如“学费”、“教室”等,就先暂时放到“课程”这个聚集根下面,等随着将来业务演进出现了新的“能一起玩儿的伙伴”后,再提取新的聚集不迟。

至此,使用限界纸笔建模法对“排课”这个核心领域所进行的建模告一段落。下图是使用这种方法对“报名”这个核心领域所建的模型,“签到”核心领域的建模略去不讨论。

9

 

这里有一个问题,“排课”这个限界上下文中有“课程”这个聚集根,而“报名”这个限界上下文中也有“课程”这个聚集根,这两者是同一个概念吗?

从DDD的观点来看,这两者是不同的概念,而且在数据库中也应该是两张不同的表。前者是“排课.课程”,后者是“报名.课程”。两者的属性也各不相同,前者是:排课.课程(名称、介绍、适合年龄、学费、教室),后者是:报名.课程(名称)。当然,这两个概念的“课程名称”和课程编号都是一致的。当“报名”限界上下文需要访问“排课”限界上下文中的“课程”概念来获取“课程介绍”等信息时,需要通过两者之间的“翻译器”来根据上述一致的课程编号来进行翻译和转换。

限界纸笔建模法的3点优势

1. 划分核心领域有助于“分而治之”:一旦确定了核心领域,限界上下文也就确定了,不同的限界上下文之间通过“翻译器”来彼此沟通并屏蔽干扰,这样就避免了“大泥球”的设计,并有助于演进到微服务架构。

2. “聚集根”有助于数据完整性:每个限界上下文都有一个“聚集根”的概念,外界对其下属概念的访问都必须通过它来进行,这样既方便定位职责,也有助于增强数据的完整性。

3. 用“纸和笔”画恰好够用的概念有助于避免过度设计:每个限界上下文中要管理的概念,都是通过“倒退到没有电脑而用纸和笔的时代如何管理”来引导出来的,用纸和笔来记录,能促使人避免写过多的信息,而只写限界上下文中恰好够用的概念。

总结

四色建模法最大的亮点是按时间发展的先后顺序,识别起“追溯单据”作用的“时标”概念,从而能把握业务核心数据,简便有效。

限界纸笔建模法,使用了DDD中的”限界上下文”与“聚集”的概念以及“纸和笔来管理”方法,来实现“分而治之”,增强数据的完整性,避免过度设计。


注:

[1] 四色建模法:经过徐昊改编的“四色建模法”参见:http://www.infoq.com/cn/articles/xh-four-color-modeling

[2] 限界上下文:Bounded Context,DDD概念,与“核心领域”(Core Domain)一一对应,它被程序员所关注,包含其所对应的核心领域的概念模型。

[3] 聚集:Aggregates,DDD概念,指某一簇彼此相关联的概念集合。

[4] 时标对象:指四色建模法中的”Moment, Interval”概念,用红色表示。近似于DDD中的Repositories概念。

[5] “人、地、物”:指四色建模法中的“Party, Place, Thing”概念,用绿色表示。近似于DDD中的Entities概念。

[6] 角色:指四色建模法中的“Role”概念,用黄色表示。近似于DDD中的Services概念。

[7] 描述信息:指四色建模法中的“Description”概念,用蓝色表示。近似于DDD中国的Value Objects概念。

[8] 聚集根:Aggregate Root,DDD概念,指对其所属的聚集内的相关从属概念进行统一访问控制的那个概念。

[9] 核心领域:Core Domain,DDD概念,与“限界上下文”(Bounded Context)一一对应,指某个业务专家所关注的、具有差异化竞争优势的、相对独立的业务领域。

[10] Entity:DDD概念,表示具有唯一标识的概念。

[11] Value Object: DDD概念,表示不必有唯一标识的概念。

Share