TranslateProject/translated/talk/20160826 Forget Technical Debt —Here'sHowtoBuild Technical Wealth.MD
2016-12-11 01:34:39 +08:00

284 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Forget Technical Debt —Here'sHowtoBuild Technical Wealth
#忘记技术债务——教你如何创造技术财富
电视里正播放着《老屋》节目,[Andrea Goulet][58]和她商业上的合作伙伴正悠闲地坐在客厅里商讨着他们的战略计划。那正是大家思想的火花碰撞出创新事物的时刻。他们正在寻求一种能够实现自身价值的方式——为其它公司清理遗留代码及科技债务。他们此刻的情景,像极了电视里的剧情。
“我们意识到我们现在做的工作不仅仅是清理出遗留代码实际上我们是在用重建老屋的方式来重构软件让系统运行更持久更稳定更高效”Goulet说。“这让我开始思考着如何让更多的公司花钱来改善他们的代码以便让他们的系统运行更高效。就好比为了让屋子变得更实用你不得不使用一个全新的屋顶。这并不吸引人但却是至关重要的然而很多人都搞错了。“
如今,她是[Corgibytes][57]公司的CEO——一家提高软件现代化和进行系统重构方面的咨询公司。她曾经见过各种各样糟糕的系统遗留代码以及不计其数的严重的科技债务事件。Goulet认为创业公司需要从偿还债务思维模式向创造科技财富的思维模式转变并且要从铲除旧代码的方式向逐步修复的方式转变。她解释了这种新的方法以及如何完成这些看似不可能完成的事情——实际上是聘用大量的工程事来完成这些工作。
### 反思遗留代码
关于遗留代码最广泛的定义由Michael Feathers在他的著作[修改代码的艺术][56][][55]一书中提出遗留代码就是没有被测试的代码。这个定义比大多数人所认为的——遗留代码仅指那些古老陈旧的系统这个说法要妥当得多。但是Goulet认为这两种定义都不够明确。“随时软件周期的生长遗留代码显得毫无用处。一两年的应用程序其代码已经进入遗留状态了”她说。“最重要的是如何提高软件质量的难易程度。”
这意味着代码写得不够清楚,缺少解释说明,没有任何关于你写的代码构件和做出这个决定的流程。一个单元测试属于一种类型的构件,也包括所有的你写那部分代码的原因以及逻辑推理相关的文档。当你去修复代码的过程中,如果没办法搞清楚原开发者的意图,那些代码就属于遗留代码了。
> 遗留代码不是技术问题,而是沟通上的问题
![](https://s3.amazonaws.com/marquee-test-akiaisur2rgicbmpehea/H4y9x4gQj61G9aK4v8Kp_Screen%20Shot%202016-08-11%20at%209.16.38%20AM.png)
如果你像Goulet所说的那样迷失在遗留代码里你会发现每一次的沟通交流过程都会变得像那条鲜为人知的[康威定律][54]所描述的一样。
Goulet说“这个定律认为系统的基础架构能反映出你们整个公司的组织沟通结构如果你想修复你们公司的遗留代码而没有一个好的组织沟通方式是不可能完成的。那是很多人都没注意到的一个重要环节。”
Goulet和她的团队成员更像是考古学家一样来研究遗留系统项目。他们根据前开发者写的代码构件相关的线索来推断出他们的思想意图。然后再根据这些构件之间的关系来作出新的决策。
最重要的代码构件是什么呢良好的代码结构、清晰的思想意图、整洁的代码。例如如果你使用了通用的名称如”foo“或”bar“来命名一个变量半年后你再返回来看这段代码时你根本就看不出这个变量的用途是什么。
如果代码读起来很困难,可以使用源代码控制系统,这是一个非常有用的构件,因为从该构件可以看出代码的历史修改信息,这为软件开发者写明他们作出本次修改的原因提供一个很好的途径。
Goulet说”我一个朋友认为对于代码注释的信息如有需要每一个概要部分的内容应该有推文的一半多而代码的描述信息应该有一篇博客那么长。你得用这个方式来为你修改的代码写一个合理的说明。这也不会浪费太多的时间并且给后期的项目开发者提供更多有用的信息但是让人惊讶的是没人会这么做。我们经常听到一些很沮丧的开发人员在调试一段代码的过程中报怨这是谁写的这烂代码最后发现还不是他们自己写的。“
使用自动化测试对于理解程序的流程非常有用。Goulet解释道“很多人都比较认可Michael Feathers提出的关于遗留代码的定义尤其是我们与[行为驱动开发模式][53]相结合的过程中使用测试套件,比如编写测试场景,这对于理解开发者的意图来说是非常有用的工具。
理由很简单,如果你想把遗留代码的程度降到最低,你得多注意下代码的易理解性以及将来回顾该代码的一些细节上。编写并运行单元程序、接受、认可,并且进行集成测试,写清楚注释的内容。方便以后你自己或是别人来理解你写的代码。
尽管如此,由于很多已知的和不可意料的原因,遗留代码仍然会发生。
在创业公司刚成立初期公司经常会急于推出很多新的功能。开发人员在巨大的压力下一边完成项目交付一边测试系统缺陷。Corgibytes团队就遇到过好多公司很多年都懒得对系统做详细的测试了。
确实如此,当你急于开发出系统原型的时候,强制性地去做太多的系统测试也许意义不大。但是,一旦产品开发完成并投入使用后,你就不得投入大量的时间精力来维护及完善系统。“很多人觉得运维没什么好担心的,重要的是产品功能特性上的强大。如果真这样,当系统规模到一定程序的时候,就很难再扩展了。同时也就失去市场竞争力了。
最后才明白过来,原来热力学第二定律对你们公司的代码也同样适用:你所面临的一切将向熵增的方向发展。你需要与混乱无序的技术债务进行一场无休无止的战斗。并且随着时间的增长,遗留代码也逐渐变成一种简单类型的债务。
她说“我们再次拿家来做比喻。你必须坚持每天收拾餐具打扫卫生倒垃圾。如果你不这么做情况将来越来越糟糕直到有一天你不得不向HazMat团队求助。”
就跟这种情况一样Corgibytes团队接到很多公司CEO的求助电话比如Features公司的CEO在电话里抱怨道“现在我们公司的开发团队工作效率太低了三年前只需要两个星期就完成的工作现在却要花费12个星期。”
> 技术债务往往反应出公司运作上的问题
很多公司的CEO明知会发生技术债务的问题但是他们也难让其它同事相信花钱来修复那些已经存在的问题是很值的。这看起来像是在走回头路很乏味或者没有新的产品。有些公司直到系统已经严重的影响了日常工作效率时才着手去处理技术债务方面的问题那时付出的代价就太高了。
### 忘记债务,创造技术财富
# 推荐文章
如果你想把[重构技术债务][52]作为一个积累技术财富的机会-[敏捷开发讲师Declan Whelan最近提到的一个术语][51]你很可能要先说服你们公司的CEO、投资者和其它的股东登上这条财富之船。
“我们没必要把技术债务想像得很可怕。当产品处于开发设计初期技术债务反而变得非常有用”Goulet说。“当你解决一些系统遗留的技术问题时你会充满成就感。例如当你在自己家里安装新窗户时你确实会花费一笔不少的钱但是之后你每个月就可以节省100美元的电费。程序代码亦是如此。这虽然暂时没有提高工作效率但是随时时间地推移将为你们公司创造更多的生产率。“
一旦你意识到项目团队工作不再富有成效时,你必须要确认下是哪些技术债务在拖后腿了。
“我跟很多不惜一切代价招募英才的初创公司交流过,他们高薪聘请一些工程师来只为了完成更多的工作。”她说。”相反的是,他们应该找出如何让原有的每个工程师都更高效率工作的方法。你需要去解决什么样的技术债务以增加额外的生产率?"
如果你改变自己的观点并且专注于创造技术财富,你将会看到产能过剩的现象,然后重新把多余的产能投入到修复更多的技术债务和遗留代码的的良性循环中。你们的产品将会走得更远,发展得更好。
> 别想着把你们公司的软件当作一个项目来看。从现在起,你把它想象成一栋自己要长久居住的房子。
“这是一个极其重要的思想观念的转变”Goulet说。“这将带你走出短浅的思维模式并且你会比之前更加关注产品的维护工作。”
这就像一栋房子,要实现其现代化的改造方式有两种:小动作,表面上的更改(“我买了一块新的小地毯!”)和大改造,需要很多年才能偿还所有债务(“我假设我们将要替换掉所有的管道...")。你必须考虑好两者才能你们已有的产品和整个团队顺利地运作起来。
这还需要提前预算好——否则那些较大的花销将会是硬伤。定期维护是最基本的预期费用。让人震惊的是,很多公司在商务上都没把维护成本预算进来。
这就是Goulet提出软件重构这个术语的原因。当你房子里的一些东西损坏的时候你不用铲除整个房子而是重新修复坏掉的那一部分就可以了。同样的当你们公司出现老的损坏的代码时重写代码通常不是最明智的选择。
下面是Corgibytes公司在重构客户代码用到的一些方法
* 把大型的应用系统分解成轻量级的更易于维护的微服务。
* 相互功能模块之间降低耦合性以便于扩展。
* 更新品牌和提升用户前端界面体验。
* 集合自动化测试来检查代码可用性。
* 重构或者修改代码库来提高易用性。
系统重构也进入到运维领域。比如Corgibytes公司经常推荐新客户使用[Docker][50]以便简单快速的部属新的开发环境。当你们公司有30个工程师的时候把初始化配置时间从10小时减少到10分钟对完成更多的工作很有帮助。系统重构不仅仅是应用于软件开发本身也包括如何进行系统重构。
如果你知道有什么新的技术能让你们的代码管理起来更容易创建更高效就应该把这它们写入到每年或季度项目规划中。你别指望它们会自动呈现出来。但是也别给自己太大的压力来马上实施它们。Goulets看到很多公司从一开始就这些新的技术进行100%覆盖率测试而陷入困境。
具体来说,每个公司都应该把以下三种类型的重构工作规划到项目建设中来:
* 自动化测试
* 持续性交付
* 文化提升
咱们来深入的了解下每一项内容
自动化测试
“有一位客户即将进行第二轮融资但是他们却没办法在短期内招聘到足够的人才。我们帮助他们引进了一种自动化测试框架这让他们的团队在3个月的时间内工作效率翻了一倍”Goulets说。“这样他们就可以在他们的投资人面前自豪的说”我们的一个精英团队完成的任务比两个普通的团队要多。“”
自动化测试从根本上来讲就是单个测试的组合。你可以使用单元测试再次检查某一行代码。可以使用集成测试来确保系统的不同部分都正常运行。还可以使用验收性测试来检验系统的功能特性是否跟你想像的一样。当你把这些测试写成测试脚本后,你只需要简单地用鼠标点一下按钮就可以让系统自行检验了,而不用手工的去梳理并检查每一项功能。
在产品的市场定位前就来制定自动化测试机制是有些言之过早了。但是如果你有一款信心满满的产品,并且也很依赖客户,那就更应该把这件事考虑在内了。
持续性交付
这是与自动化交付相关的工作,过去是需要人工完成。目的是当系统部分修改完成时可以迅速进行部属,并且短期内得到反馈。这给公司在其它竞争对手面前有很大的优势,尤其是在售后服务行业。
“比如说你每次部属系统时环境都很复杂。熵值无法有效控制”Goulets说。“我们曾经花了12个小时甚至更多的时间来部属一个很大的集群环境。然而想必你将来也不会经常干部属新环境这样的工作。因为太折腾人了而且还推迟了系统功能上线的时间。同时你也落后于其它公司并失去竞争力了。
在持续性改进的过程中常见的其它自动化任务包括:
* 在提交完成之后检查中断部分。
* 在出现故障时进行回滚操作。
* 审查自动化代码的质量。
* 根据需求增加或减少服务器硬件资源。
* 让开发,测试及生产环境配置简单易懂。
举一个简单的例子比如说一个客户提交了一个系统Bug报告。开发团队越高效解决并修复那个Bug越好。对于开发人员来说修复Bug的挑战根本不是个事儿这本来也是他们的强项主要是系统设置上不够完善导致他们浪费太多的时间去处理bug以外的其它问题。
使用持续改进的方式时,在你决定哪些工作应该让机器去做还是最好丢给研发去完成的时候,你会变得很严肃无情。如果选择让机器去处理,你得使其自动化完成。这样也能让研发很愉快地去解决其它有挑战性的问题。同时客户也会很高兴地看到他们报怨的问题被快速处理了。你的待修复的未完成任务数减少了,之后你就可以把更多的时间投入到运用新的方法来提高公司产品质量上了。
”你必须时刻问自己我应该如何为我们的客户改善产品功能如何做得更好如何让产品运行更高效Goulets说。“一旦你回答完这些问题后你就得询问下自己如何自动去完成那些需要改善的功能”
提升企业文化
Corgibytes公司每天都会遇到同样的问题一家创业公司建立了一个对开发团队毫无影响的文化环境。公司CEO抱着双臂思考着为什么这样的环境对员工没多少改变。然而事实却是公司的企业文化观念与他们是截然相反的。为了激烈你们公司的工程师你必须全面地了解他们的工作环境。
为了证明这一点Goulet引用了作者Robert Henry说过的一段话
> 目的不是创造艺术,而是在最美妙的状态下让艺术应运而生。
“也就是说你得开始思考一下你们公司的产品,“她说。”你们的企业文件就应该跟自己的产品一样。你们的目标是永远创造一个让艺术品应运而生的环境,这件艺术品就是你们公司的代码,一流的售后服务、充满幸福感的员工、良好的市场、盈利能力等等。这些都息息相关。“
优先考虑公司的技术债务和遗留代码也是一种文化。那才是真正能让开发团队深受影响的方法。同时这也会让你将来有更多的时间精力去完成更重要的工作。如果你不从根本上改变固有的企业文化环境你就不可能重构公司产品。改变你所有的对产品维护及现代化上投资的态度是开始实施变革的第一步最理想情况是从公司的CEO开始转变。
以下是Goulet关于建立那种流态文化方面提出的建议
* 反对公司嘉奖那些加班到深夜的”英雄“。提倡高效率的工作方式。
* 了解协同开发技术比如Woody Zuill提出的[暴徒编程][44][][43]模式。
* 遵从4个[现代敏捷开发][42] 原则:用户至上、实践及快速学习、把系统安全放在首位、持续交付价值。
* 每周为研发提供项目外的职业发展时间。
* 把[日工作记录]作为一种驱动开发团队主动解决问题的方式。
* 把同情心放在第一位。Corgibytes公司让员工参加[Brene Brown勇气工厂][40]的培训是非常有用的。
”如果公司高管和投资者不支持这种文件升级方式你得从客户服务的角度去说服他们“Goulet说”告诉他们通过这次调整后最终产品将如何给公司的大客户提高更好的体验。这是你能做的一个很有力的论点。“
### 寻找最具天财的代码重构者
整个行业都认为那些顶尖的工程师都不愿意去干修复遗留代码的工作。他们只想着去开发新的东西。大家都说把他们留在维护部门真是太浪费人才了。
其实这些都是误解。如果你知道如何寻找到那些技术精湛的工程师以为他们提供一个愉快的工作环境,你可以安排他们来帮你解决那些最棘手的技术债务问题。
”每一次开会的时候我们都会问现场的同事谁喜欢去干遗留代码的工作但是也只有那么不到10%的同事会举手。“Goulet说。”但是当我跟这些人交流的过程中我发现这些工程师恰好是喜欢最具挑战性工作的人才。“
有一位客户来寻求她的帮助他们使用国产的数据库没有任何相关文档也没有一种有效的方法来弄清楚他们公司的产品架构。她称那些类似于面包和黄油的一类工程师为”修正者“。在Corgibytes公司她有一支这样的修正者团队由她支配他们没啥爱好只喜欢通过研究二进制代码来解决技术问题。
![](https://s3.amazonaws.com/marquee-test-akiaisur2rgicbmpehea/BeX5wWrESmCTaJYsuKhW_Screen%20Shot%202016-08-11%20at%209.17.04%20AM.png)
那么如何才能找到这些技术人才呢Goulet尝试过各种各样的方法其中有一些方法还是富有成效的。
她创办了一个社区网站[legacycode.rocks][49]并且在招聘启示上写道:”长期招聘那些喜欢重构遗留代码的另类开发人员...如果你以从事处理遗留代码的工作为自豪,欢迎加入!“
”我刚开始收到很多这些人发来邮件说,’噢,天呐,我也属于这样的开发人员!‘“她说。”我开始发布这条信息,并且告诉他们这份工作是非常有意义的,以吸引合适的人才“
推荐文章
在招聘的过程中,她也会使用持续性交付的经验来回答那些另类开发者想知道的信息:包括详细的工作内容以及明确的要求。我这么做的原因是因为我讨厌重复性工作。如果我收到多封邮件来咨询同一个问题,我会把答案发布在网上,我感觉自己更像是在写说明文档一样。”
但是随着时间的推移她注意到她会重新定义招聘流程来帮助她识别出更出色的候选人。比如说她在应聘要求中写道“公司CEO将会重新审查你的简历因此确保邮件发送给CEO时”不用写明性别。所有以“尊敬的先生或女士”开头的信件将会被当垃圾处理掉。然后这只不过是她招聘初期的策略而已。
“我开始这么做是因为很多申请人把我当成一家软件公司的男性CEO这让我很厌烦”Goulet说。“所有有一天我想我应该它当作应聘要求放到网上看有多少人注意到这个问题。令我惊讶的是这让我过滤掉一些不太严谨的申请人。还突显出了很多擅于从事遗留代码方面工作的人。
Goulet想起一个应聘者发邮件给我说“我查看了你们网站的代码我喜欢这个网站以及你们打招呼的方式这就是我所希望的。你们的网站架构很奇特好像是用PHP写的但是你们却运行在用Ruby语言写的Jekyll下。我真的很好奇那是什么呢。”
原来是这样的Goulet从她的设计师那里得知在HTML、CSS和JavaScript文件中有一个未使用的PHP类名她一直想解决这个问题但是一直没机会。她的回复是“你正在找工作吗
另外一名候选人注意到她曾经在一篇说明文档中使用CTO这个词但是她的团队里并没有这个头衔她的合作伙伴是首席代码语者。其次是那些注重细节、充满求知欲、积极主动的候选者更能引起她的注意。
> 代码修正者不仅需要注重细节,而且这也是他们必备的品质。
让人吃惊的是Goulet从来没有为招募最优秀的代码修正者而感到厌烦过。”大多数人都是通过我们的网站直接投递简历但是当我们想扩大招聘范围的时候我们会通过[PowerToFly][48]和[WeWorkRemotely][47]网站进行招聘。我现在确实不需要招募新人马了。他们需要经历一段很艰难的时期才能理解代码修正者的意义是什么。“
如果他们通过首轮面试Goulet将会让候选者阅读一篇Arlo Belshee写的文章”[命名是一个过程][46]“。它讲的是非常详细的处理遗留代码的的过程。她最经典的指导方法是:”阅读完这段代码并且告诉我,你是怎么理解的。“
她将找出对问题的理解很深刻并且也愿意接受文章里提出的观点候选者。这对于筛选出有坚定信念的想被雇用的候选者来说是极其有用的办法。她强力要求候选者找出一段与你操作相关的最关键的代码来证明你是充满激情的、有主见的及善于分析问题的人。
最后,她会让候选者跟公司里当前的团队成员一起使用[Exercism.io][45]工具进行编程。这是一个开源项目,它允许开发者学习如何在不同的编程语言环境下使用一系列的测试驱动开发的练习进行编程。第一部分的协同编程课程允许候选者选择其中一种语言进行内建。下一个练习中,面试者可以选择一种语言进行编程。他们总能看到那些人处理异常的方法、随机应便的能力以及是否愿意承认某些自己不了解 的技术。
“当一个人真正的从专家转变为大师的时候他才会毫不犹豫的承认自己不知道的东西“Goulet说。
让他们使用自己不熟悉的编程语言来写代码也能衡量其坚韧不拔的毅力。”我们想听到某个人说,‘我会深入研究这个问题直到彻底解决它。“也许第二天他们仍然会跑过来跟我们说,’我会一直留着这个问题直到我找到答案为止。‘那是作为一个成功的修正者表现出来的一种气质。“
> 如果你认为产品开发人员在我们这个行业很受追捧,因此很多公司也想让他们来做维护工作。那你可错了。最优秀的维护修正者并不是最好的产品开发工程师。
如果一个有天赋的修正者在眼前Goulet懂得如何让他走向成功。下面是如何让这种类型的开发者感到幸福及高效工作的一些方式
* 给他们高度的自主权。把问题解释清楚,然后安排他们去完成,但是永不命令他们应该如何去解决问题。
* 如果他们要求升级他们的电脑配置和相关工具,尽管去满足他们。他们明白什么样的需求才能最大限度地提高工作效率。
* 帮助他们[避免更换任务][39]。他们喜欢全身心投入到某一个任务直至完成。
总之这些方法已经帮助Corgibytes公司培养出20几位对遗留代码充满激情的专业开发者。
### 稳定期没什么不好
大多数创业公司都都不想跳过他们的成长期。一些公司甚至认为成长期应该是永无止境的。而且,他们觉得也没这个必要,即便他们已经进入到了下一个阶段:稳定期。完全进入到稳定期意味着你可以利用当前的人力资源及管理方法在创造技术财富和消耗资源之间做出一个正确的选择。
”在成长期和稳定期之间有个转折点就是维护人员必须要足够壮大并且你开始更公平的对待维护人员以及专注新功能的产品开发人员“Goulet说。”你们公司的产品开发完成了。现在你得让他们更加稳定地运行。“
这就意味着要把公司更多的预算分配到产品维护及现代化方面。”你不应该把产品维护当作是一个不值得关注的项目,“她说。”这必须成为你们公司固有的一种企业文化——这将帮助你们公司将来取得更大的成功。“
最终,你通过这么努力创建的技术财富将会为你的团队带来一大批全新的开发者:他们就像侦查兵一样,有充足的时间和资源去探索新的领域,挖掘新客户资源并且给公司创造更多的机遇。当你们在新的市场领域做得更广泛并且不断发展得更好——那么你们公司已经真正地进入到繁荣发展的状态了。
--------------------------------------------------------------------------------
via: http://firstround.com/review/forget-technical-debt-heres-how-to-build-technical-wealth/
作者:[http://firstround.com/][a]
译者:[rusking](https://github.com/rusking)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://firstround.com/
[1]:http://corgibytes.com/blog/2016/04/15/inception-layers/
[2]:http://www.courageworks.com/
[3]:http://corgibytes.com/blog/2016/08/02/how-we-use-daily-journals/
[4]:https://www.industriallogic.com/blog/modern-agile/
[5]:http://mobprogramming.org/
[6]:http://exercism.io/
[7]:http://arlobelshee.com/good-naming-is-a-process-not-a-single-step/
[8]:https://weworkremotely.com/
[9]:https://www.powertofly.com/
[10]:http://legacycode.rocks/
[11]:https://www.docker.com/
[12]:http://legacycoderocks.libsyn.com/technical-wealth-with-declan-wheelan
[13]:https://www.agilealliance.org/resources/initiatives/technical-debt/
[14]:https://en.wikipedia.org/wiki/Behavior-driven_development
[15]:https://en.wikipedia.org/wiki/Conway%27s_law
[16]:https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
[17]:http://corgibytes.com/
[18]:https://www.linkedin.com/in/andreamgoulet
[19]:http://corgibytes.com/blog/2016/04/15/inception-layers/
[20]:http://www.courageworks.com/
[21]:http://corgibytes.com/blog/2016/08/02/how-we-use-daily-journals/
[22]:https://www.industriallogic.com/blog/modern-agile/
[23]:http://mobprogramming.org/
[24]:http://mobprogramming.org/
[25]:http://exercism.io/
[26]:http://arlobelshee.com/good-naming-is-a-process-not-a-single-step/
[27]:https://weworkremotely.com/
[28]:https://www.powertofly.com/
[29]:http://legacycode.rocks/
[30]:https://www.docker.com/
[31]:http://legacycoderocks.libsyn.com/technical-wealth-with-declan-wheelan
[32]:https://www.agilealliance.org/resources/initiatives/technical-debt/
[33]:https://en.wikipedia.org/wiki/Behavior-driven_development
[34]:https://en.wikipedia.org/wiki/Conway%27s_law
[35]:https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
[36]:https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
[37]:http://corgibytes.com/
[38]:https://www.linkedin.com/in/andreamgoulet
[39]:http://corgibytes.com/blog/2016/04/15/inception-layers/
[40]:http://www.courageworks.com/
[41]:http://corgibytes.com/blog/2016/08/02/how-we-use-daily-journals/
[42]:https://www.industriallogic.com/blog/modern-agile/
[43]:http://mobprogramming.org/
[44]:http://mobprogramming.org/
[45]:http://exercism.io/
[46]:http://arlobelshee.com/good-naming-is-a-process-not-a-single-step/
[47]:https://weworkremotely.com/
[48]:https://www.powertofly.com/
[49]:http://legacycode.rocks/
[50]:https://www.docker.com/
[51]:http://legacycoderocks.libsyn.com/technical-wealth-with-declan-wheelan
[52]:https://www.agilealliance.org/resources/initiatives/technical-debt/
[53]:https://en.wikipedia.org/wiki/Behavior-driven_development
[54]:https://en.wikipedia.org/wiki/Conway%27s_law
[55]:https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
[56]:https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
[57]:http://corgibytes.com/
[58]:https://www.linkedin.com/in/andreamgoulet