务实,扩展, 提升, 质量
## Summary 概括
**- Why do i read it? 我为什么要读这本书?**
学习如何做一个合格的程序员, 如何向变成编程大师更进一步
**- How the Book Changed Me? 这本书怎样影响了我?**
1. 作为一个程序员只要你足够优秀, 你还是会拥有很多机会的
2. 不要容忍破窗 ( 实际写代码中, 我可能还是会容忍)
3. 更加坚定的使用vim和shell作为自己日常文档,代码工具, 纯文本的力量
**- The book in 3 Sentences? 书中的三句精华句子?**
1. 这个行业给了你一系列非凡的机遇。积极主动点,掌控这些机遇。
2. 你想要一根香蕉,但得到的却是一只拿着香蕉的大猩猩,甚至还有整个丛林。
——乔·阿姆斯 (关于类型继承)
4. 我们想看到你对所有权引以为豪——“这是我写的,我与我的作品同在”。你的签名应该被认为是质量的标志。
**- My Top 3 Quotes? 三句话总结本书**
1. 程序员职业还是充满机会
2. 追求代码质量, 多写单元测试, 脚本工具自动化
3. 不断的学习, 拓宽思维, 提升技能和软实力
## Literature 书摘
我们和很多沮丧的开发者交谈过。他们的担忧多种多样。一些人感觉自己的工作停滞不前。还有一些人认为自己的技术已经过时了。有人觉得自己没有得到应有的重视,有人觉得薪水过低,有人觉得团队已经一团糟。一些人想去亚洲或是欧洲工作,一些人想在家工作。 对此,我们总是给出相同的答案。 “为什么你不考虑改变一下呢?”
==========
这个行业给了你一系列非凡的机遇。积极主动点,掌控这些机遇。
==========
想远程工作?要求过了吗?如果他们说不行,就去找个说行的人。
==========
如果你的技术过时了,安排时间(你自己的时间)学习一些看起来有趣的新东西。这是一种自我投资,只有为此而加班才是合理的。
==========
在你的职业发展、学习教育,以及你的项目、每天的工作等各方面对你自己负责,对你的行为负责,这是务实哲学的基石之一。
==========
但面对缺点时也必须诚实——承认我们犯了错误,而且是因为我们的无知而犯下的。
==========
责任意味着你对某事积极认同。你保证事情能搞定,并为之做出承诺,但你不必直接掌控事情的每个方面。除了个人尽力做好,你必须分析超出你控制范围的风险情况。
==========
这些因素都可能是问题的一部分。它们的确会对解决方案造成影响,但不是给你的借口。
==========
不要把问题归咎于别人或其他什么事情上,也不要寻找借口。不要把所有问题都归咎于供应商、编程语言、管理或是同事。这些因素都可能是问题的一部分。它们的确会对解决方案造成影响,但不是给你的借口。
==========
解释一下要做些什么才能挽回这个局面。
==========
· 当某人——比如银行职员、汽车修理工、店员——敷衍搪塞你时,你的反应是什么?你会怎么看他们和他们的公司?
==========
当你意识到自己在说“我不知道”时,一定要接着说“——但是我会去搞清楚”。
==========
当你意识到自己在说“我不知道”时,一定要接着说“——但是我会去搞清楚”。用这样的方式来表达你不知道是非常好的,因为接着你就可以像一个专家一样承担起责任。
==========
当软件中的无序化增加时,程序员会说“软件在腐烂”。有些人可能会用更乐观的术语来称呼它,即“技术债”,潜台词是说他们总有一天会偿还的——恐怕不会还了。
==========
一扇破损的窗户,只要一段时间不去修理,建筑中的居民就会潜移默化地产生一种被遗弃的感觉——当权者不关心这幢建筑的感觉。然后,其他的窗户也开始损坏,居民开始乱丢废物,墙上开始出现涂鸦,建筑开始出现严重的结构性损坏。在一段看上去很短的时间内,建筑的损坏程度就足以打消业主们想修好它的期望,被遗弃的感觉最终变成了现实。 为何造成这样的影响?心理学家的研究[4]表明,绝望是会传染的,就像狭窄空间中的流感病毒。无视一个明显损坏的东西,会强化这样一种观念:看来没有什么是能修好的,也没人在乎,一切都命中注定了。所有的负面情绪会在团队成员间蔓延,变成恶性循环。
==========
现在我们了解了一旦窗户开始破裂,运转良好的干净系统会迅速恶化。还有一些其他因素会导致软件腐烂,我们将在别处探讨,但与其他任何因素相比,漠视会加速腐烂的过程。
==========
反正代码所有其他部分都是一坨屎,我只是随大流而已。”
==========
破窗理论中,人们失去打败熵的斗志是因为他们觉得没其他人在乎。而青蛙仅仅只是未察觉到变化。
==========
为了追求更好,我们毁损了原已够好的。 ——莎士比亚《李尔王1.4》
==========
上,知识和经验的确是你最重要的专业资产。
==========
1.正规投资者有定期投资的习惯。 2.多样化是长线成功的关键。 3.聪明的投资者会平衡保守型和高风险高回报型投资的组合。 4.投资者用低买高卖来获得最大的回报。 5.应定期审查和重新平衡投资组合。
==========
现在你已经有了一些指导方针,知道什么时候添加什么内容到知识组合中。
==========
每年学习一门新语言 不同的语言以不同的方式解决相同的问题。
==========
每月读一本技术书
==========
我们称这些为软技能,听起来很容易,但实际上它们很硬核,难以掌握)。
==========
还要读非技术书 记住,计算机是由人来使用的,你做的事情是为了满足人的需要,这
==========
不要只是去当听众,要主动参与。独来独往对你的职业生涯是致命的;了解一下公司之外的人们都在做什么。
==========
我最喜欢的咨询技巧是:至少问五次“为什么”。就是说,每当有了答案后,还要追问“为什么”。像个烦人的四岁小孩那样经常性重复提问,不过记得要比小朋友更有礼貌。这样做可以让你更接近本源。
==========
既然你已经知道了听众想要什么,那么是时候计划如何去做了。
==========
随便一个厨师(或者是美食频道的主持人)都会告诉你,仅仅是糟糕的外观就能毁掉你在厨房里埋头苦干几个小时的成果。 今天,
==========
随便一个厨师(或者是美食频道的主持人)都会告诉你,仅仅是糟糕的外观就能毁掉你在厨房里埋头苦干几个小时的成果。 今天,我们已找不到借口制作出版式丑陋的文档。
==========
随时知会别人,能让人更容易原谅你偶然的疏忽,让人觉得你并没有忘记他们。
==========
让文档总是在手边——直接写在代码里。
==========
我们要避免重复劳动和浪费时间,让文档总是在手边——直接写在代码里。
==========
能适应使用者的就是好的设计。对代码而言,就是要顺应变化。因此要信奉ETC原则(Easier To Change,更容易变更)——就该如此。
==========
你会发现DRY原则将在本书中一次又一次地出现,而且经常出现在与编码无关的语境中。我们认为它是务实程序员的工具箱中最重要的工具之一。
==========
并非所有的代码重复都是知识的重复
==========
在代码复审时,几个来自夜郎国的家伙挑出了这段代码,声称这违背了DRY:这两个函数体完全一样。 他们错了。代码的确相同,但代码所表达的知识是不同的。这两个函数校验了两个不相干的东西,只是恰巧使用了相同的规则。这是一个巧合,而非重复。
==========
一个模块提供的所有服务都应该通过统一的约定来提供,该约定不应表露出其内部实现是基于储存还是基于运算的。
==========
开发人员间的重复 最难检测到且最难处理的重复类型,可能发生在同一项目的不同的开发人员之间。整块的功能集可能会在不经意间重复,而这种重复或许好几年都未被发现,最终导致了维护问题。
==========
要重视阅读其他人的源码和文档,不管使用非正式的形式还是通过正式的代码审核。
==========
在计算科学中,这个术语象征着独立性或解耦性。对于两个或多个事物,其中一个的改变不影响其他任何一个,则这些事物是正交的。
==========
突然间,你要应付一个难以置信的复杂系统,系统中每个变化都影响着其他输入。你的工作负担惊人的巨大:手脚不断移动,试图平衡所有的交互力。
==========
但凡编写正交的系统,就能获得两个主要的收益:提高生产力及降低风险。
==========
将变更限制在局部后,开发时间和测试时间都会减少。
==========
组合正交组件能获得相当微妙的生产力提升。假设一个组件能做M件独特的事情,另一个能做N件。如果它们是正交的,组合起来就能做M×N件事。
==========
· 代码中病变的部分被隔离开。如果一个模块生病了,不太可能将症状传播到系统的其他部分。
==========
这种分层的实现是设计正交系统的有力途径。因为每一层只使用它下面一层提供的抽象,所以可以在不影响代码的情况下极其灵活地更改底层实现。
==========
都是外部标识符,你无法完全控制,它们都可能因为某些原因而改变。不要依赖那些你无法控制的东西。
==========
EJB的这个方式是修饰模式的一个范例:给一个事物添加功能却不需要修改事物本身。
==========
模块不会向其他模块透露任何不必要的信息,也不依赖于其他模块的实现。
==========
只要代码引用全局数据,就会将自己绑定到共享该数据的其他组件上。即使只打算对全局数据进行读操作,也可能引发问题(例如突然需要将代码改为多线程的情形)。
==========
只要代码引用全局数据,就会将自己绑定到共享该数据的其他组件上。即使只打算对全局数据进行读操作,也可能引发问题(例如突然需要将代码改为多线程的情形)。一般来说,如果总是显式地将任何需要的上下文传递给模块,那么代码会更容易理解和维护。
==========
编写单元测试本身就是一个有趣的正交性测试。做什么才能让单元测试构建出来并运行起来?需要导入系统其余的大部分代码吗?如果是这样,那么就已经发现了一个与系统其余部分没有很好地解耦的模块。
==========
与其认为决定是被刻在石头上的,还不如把它们想象成写在海滩的沙子上。
==========
我们使用曳光弹式开发这个术语,来直观地说明,在真实条件下针对移动目标进行即时反馈的必要性。
==========
因为用户以前从未见过这样的系统,所以需求可能是模糊的。或许你可能正在使用不熟悉的算法、技术、语言或库,因此将面临大量的未知因素。由于项目需要时间去完成,所以几乎可以确定,在完成之前,工作所处的环境一定会改变。
==========
曳光弹式开发和项目不会结束这种理念是一致的:总有东西需要改,总有新功能需要加。这是一个逐步递增的方法。
==========
你可以每天(通常是一天多次)持续集成,而不必去面对一个巨量的集成工作。
==========
这一区别非常重要,值得我们反复强调。原型生成的是一次性代码;曳光代码虽然简单但是完整,它是最终系统框架的组成部分。
==========
原型被设计出来,只是为了回答几个问题,因此比要投入生产的应用程序成本更低,开发速度更快。
==========
把这项技能发展为对事物的数量级产生直觉,你将能展现出一种魔法般的能力,这种能力可以判别事情的可行性。
==========
所以当有人让你估算的时候,你要问自己的第一个问题是,答案会用在什么场合下。
==========
我们建议你采用下面的时间尺度做估算:
==========
所有的估算都是基于对问题的建模。但是在我们深入建模技术之前,必须提到一个基本的估算技巧,用它总能给出不错的答案:问问已经做过的人。
==========
每个 PERT 任务都有一个乐观的、一个最有可能的和一个悲观的估算。
==========
只要重复下列步骤做增量开发,这未必是个悖论。[17] · 检查需求 · 分析风险 · 设计、实现、集成 · 和用户一起验证
==========
应该说“我等一下答复你。” 放慢节奏,花点时间完成本部分中描述的步骤,你总能得到更好的结果。在咖啡机旁边给出的估算会(像咖啡一样)反过来消磨掉你的时间。
==========
· 为防备老化而加保险 · 利用杠杆效应让已有工具发挥最大优势 · 易于测试
==========
但是,如果使用图形界面去完成所有工作,就会错失环境的全部能力。你将无法把常见的任务自动化,或是无法充分利用工具所能提供的强大功能。并且,你也无法通过组合你的工具来创建定制的宏工具。图形工具的好处在于WYSIWYG ——所见即所得;弱势之处是WYSIAYG——所见即全部。
==========
GUI环境通常局限于其设计者所期望的功能。
==========
任何一个单一工具的使用范围,通常都局限于该工具预期执行的任务。
==========
你会花很多时间住在某个Shell里,像寄居蟹一样,把Shell当成自己的家。
==========
提示29 去解决问题,而不是责备 Bug 是你的错还是别人的错并不重要。无论是谁的错,问题仍然要你来面对。
==========
· 人为的测试(例如程序员从下到上画线)对应用程序的测试而言还不够。你必须粗暴地测试所有边界条件,并且复原实际的最终用户使用模式。你需要有系统地做这些事情(参见第283页的无情的持续测试)。
==========
有一个非常简单但特别有用的方法,可以用来找到问题的原因,那就是向其他人解释该问题。
==========
你必须明确地陈述自己检查代码时可能认为理所当然的事情。通过把这些假设用语言表达出来,
==========
如果修复这个 Bug花了很长时间,问问自己为什么。你能做些什么来让下次修复这个Bug 更容易呢?也许可以构建更好的测试钩子,或是编写一个日志文件分析器。
==========
提示35 学习一门文本处理语言 为了展示文本处理语言的广泛适用性,下面的例子是我们用 Ruby 和 Python
==========
提示35 学习一门文本处理语言
==========
所以我们被教导要防御式编程——有任何疑问,都要去验证我们得到的一切信息;
==========
文档化及对主张进行检验是契约式设计(缩写为 DBC)的核心。
==========
TDD 是一项伟大的技术,
==========
简单地列出输入域的范围、边界条件是什么、例程承诺要交付什么——或者更重要的是,没有承诺要交付什么——这些对编写更好的软件来说,是一个巨大的飞跃。
==========
但我们在防御性编码——要确保数据是我们想要的,确保产品中使用的代码就是我们以为的那些代码,我们会检查依赖项的正确版本是否已经加载。
==========
一句反复被引用的话:“防御式编程是在浪费时间,让它崩溃!”
==========
基本原理是一样的——一旦代码发现本来不可能发生的事情已发生,程序就不再可靠。从这一时刻开始,它所做的任何事情都是可疑的,所以要尽快终止它。 一个死掉的程序,通常比一个瘫痪的程序,造成的损害要小得多。
==========
自责中往往有种奢侈。我们自责时,总觉得别人无权再责备我们。 ——奥斯卡·王尔
==========
三个例程因为共享变量customer_file耦合在了一起,而且对文件何时是打开状态、何时是关闭状态的跟踪开始变得混乱。我们正掉入一个陷阱,如果继续走这条路,
==========
三个例程因为共享变量customer_file耦合在了一起,而且对文件何时是打开状态、何时是关闭状态的跟踪开始变得混乱。我们正掉入一个陷阱,如果继续走这条路,情况将开始迅速恶化。这是不平衡的!
==========
分配资源的例程也应该负责释放它。
==========
释放资源的顺序与分配资源的顺序相反。
==========
就始终以相同的顺序分配它们。
==========
别超过你能看见的范围。越是必须预测未来会怎样,就越有可能犯错。
==========
我们的代码很快便会过时,或是因太脆弱而无法在出错后修复,最终都可能在疯狂冲向未来的过程中被抛在后面。
==========
提示45 只管命令不要询问 这个原则说的是,不应该根据对象的内部状态做出决策,然后更新该对象。这样做完全破坏了封装的优势,并且在这样做时,也会把实现相关的知识扩散到整个代码中。
==========
TDA(tell-don't-ask,只管命令不要询问)的问题,我们不应该取出订单列表再从中搜索,
==========
LoD 说的是,定义在C 类中的函数只应该调用: · C类其他实例的方法 · 它的参数
==========
LoD 说的是,定义在C 类中的函数只应该调用: · C类其他实例的方法 · 它的参数 · 它所创建出来的对象的方法,包括在栈上和堆上的对象 · 全局变量 在这
==========
修改全局变量的实现,可能会潜在地影响到系统中的所有代码。
==========
提示47 避免全局数据
==========
全局数据包括外部资源 任何可变的外部资源都是全局数据。如果应用程序使用了数据库、数据存储、文件系统、服务 API等,那么它就有落入全局化陷阱的风险。同样,解决方案是确保始终将这些资源包装在你所控制的代码之后。
==========
让代码害羞一点:让它只处理直接知道的事情,这将有助于保持应用程序解耦,使其更易于变更。
==========
事情不会随随便便发生,它们是注定要发生的。 ——约翰·肯尼迪
==========
事件表达出信息的可用性。
==========
字符串。这里有一个FSM可以做到这些: 这一次,每个转换都有两个标签。上面一个是触发它的事件,下面一个是我们在状态之间移动时要采取的动作。
==========
状态机是一个开始 状态机并没有被开发人员充分利用,我们鼓励你找机会多用用。但其并不能解决所有与事件相关的问题。
==========
此外,由于在典型的实现中,回调是由观察对象以同步的方式内联处理的,因此可能会导致性能瓶颈。
==========
与观察者模式相比,pubsub模式是一个通过用共享接口(信道)进行抽象来减少耦合的好例子。
==========
如果你不能将正在做的事情描述为一个流程,那表示你不知道自己正在做什么。 ——爱德华兹·戴明(出处待考)
==========
永远不在变换之间传递原始值。取而代之的是,将值封装在一个数据结构(或类型)中,该结构可以告知我们所包含的值是否有效。
==========
你想要一根香蕉,但得到的却是一只拿着香蕉的大猩猩,甚至还有整个丛林。 ——乔·阿姆斯
==========
我们面对的是 OO开发者这一代人,他们使用继承有两个原因:一个是不喜欢拍键盘,另一个是喜欢类型。
==========
更好的替代方案 让我们推荐三种技术,它们意味着你永远不需要再使用继承: · 接口与协议 · 委托 · mixin 与特征
==========
接口与协议之所以如此强大,是因为我们可以将它们用作类型,而实现适当接口的任何类都将与该类型兼容。
==========
继承鼓励开发人员创建这样的对象,其类拥有大量的方法。如果父类有 20 个方法,而子类只想使用其中的两个,那么其对象还是会将其他 18 个方法放在那里,并使其能被调用。类失去了对其接口的控制。
==========
有一个”胜过“是一个”
==========
这就是我们在研究mixin时要解决的问题。基本思想很简单:希望能够为类和对象扩展新的功能,但不用继承。那么就创建一组函数,给这个函数组起一个名字,然后用它去扩展一个类或对象。至此,你就创建出了一个新的类或对象,它组合了原始类及所有 mixin 的特性。在大多数情况下,即使无法使用要扩展的类的源码,也可以进行此扩展。
==========
而是将配置信息包装在一个(瘦)API后面。这将使代码从配置的呈现细节中解耦出来。
==========
配置应该是动态的,这在我们转向高可用性应用程序时至关重要。为了改变单个参数就必须停下来重启应用程序,这样的想法已完全脱离当前的现实。
==========
而是没有哪个进程能保证二者对内存的认知前后一致。
==========
当前的设计很糟糕,因为该设计将保护陈列柜访问权的责任委托给了使用它的人。让我们做出改变,将其调整为集中控制。要做到这一点,我们必须改变 API,
==========
务实的程序员会对所有代码进行批判性思考,包括自己的代码。我们不断看到程序和设计的改进空间。 在重构中,关注的是那些帮助我们在前进中持续改进已有代码的技巧。
==========
测试的主要收益来自于你思考和编写测试期间,而不是运行测试那一刻。
==========
最后,命名是软件开发中最困难的事情之一。
==========
开始一个新项目(甚至是现有项目中的一个新模块)有可能让人不安。因此,我们中的许多人宁愿推迟迈出第一步。
==========
Fred不知道为什么代码会出错,因为他一开始就不知道它为什么能工作。
==========
不要假设,要证明。
==========
大 O永远不会告诉你时间、内存或其他什么资源的真正开销数值:它只是告诉你数值会怎样跟着输入的量而变化。
==========
还须注意不要过早地优化。在投入宝贵的时间尝试改进算法之前,确保算法确实是瓶颈,总是最为可取。
==========
罗伯特·塞奇威克写了一系列关于这个主题的通俗易懂的书(《算法》[SW11]、《算法分析导论》[SF13],等等)。
==========
高德纳的那套权威的《计算机程序设计艺术》,
==========
代码需要演化;它不是一个静态的东西。
==========
我们相信,测试获得的主要好处发生在你考虑测试及编写测试的时候,而不是在运行测试的时候。
==========
在一个测试数据库上运行测试。但对于我们这个案例,这意味着我们应该向函数传递数据库实例,而不是使用全局实例,因为这样我们才能在测试时改变该实例:
==========
我们认为这可能是测试所提供的最大好处:测试所提供的反馈至关重要,可以指导编码过程。
==========
在你能对一个东西做测试之前,必须先理解它。虽然听起来很傻,但现实中我们开始编写代码,都只能基于对必须要做的事情的模糊理解。我们打算边干边解决。哦,稍后还会添加支持边界条件的所有代码。哦,还有错误处理要完成。这样进行下去,代码会比它应有的长度长五倍,因为它充满了条件逻辑和特殊情况。但是,如果用测试先探照一下代码,事情就会变得更清楚。如果你在开始编写代码之前,就考虑过测试边界条件及其工作方式,那么就很可能会发现简化函数的逻辑模式。如果你考虑过需要测试的错误条件,那么将会相应地去构造这个函数。
==========
然而,我们也看到人们成为 TDD 的奴隶。
==========
我们看到了 TDD对于从测试着手做事的人的主要好处。只要遵循 TDD 工作流程,就能保证代码始终都有测试。这意味着你会一直处于考虑测试的状态。
==========
我们坚信,构建软件的唯一方法是增量式的。构建端到端功能的小块,一边工作一边了解问题。应用学到的知识持续充实代码,让客户参与每一个步骤并让他们指导这个过程。
==========
在调试完以后,需要把这个临时测试正式化。如果代码出过一次问题,就有再出问题的可能性。不要将创建出来的测试扔掉,把它添加到现有的单元测试库中。
==========
包含跟踪消息的日志文件就是这样一种机制。日志消息应该采用规范一致的格式;你可能希望自动解析日志以推断程序的处理时间或逻辑路径。糟糕的或格式不一致的诊断信息非常“恶心”——它们难以阅读,也不好解析。
==========
我的个性坚持认为,当开始觉得舒适的时候,就应该去尝试别的东西。
==========
考虑测试的最大好处之一就是它能指导你写代码。
==========
代码复杂性滋生攻击
==========
代码复杂性滋生攻击载体
==========
你的应用程序实现了不同级别的访问吗?级别划分是不是很生硬,仅分为“管理员”和“用户”?如果是,请考虑更细的粒度,比如敏感资源可划分为不同的类别,单个用户仅对其中部分类别具有权限。
==========
不要把保密内容、API 密钥、SSH 密钥、加密密码或其他凭据,和源码一起提交到版本控制
==========
美国的 NIST和英国的国家网络安全中心都特别要求校验方允许粘贴功能。
==========
不要禁用浏览器中的粘贴功能。破坏浏览器和密码管理器的功能,并不能使系统更安全。实际上,它会促使用户创建更简单、更短、更容易破解的密码。出于这个原因,美国的 NIST和英国的国家网络安全中心都特别要求校验方允许粘贴功能。
==========
名不正,则言不顺;言不顺,则事不成。 ——孔子
==========
只要你有所创造,就需要停下来思考“我这一创造的动机是什么?”
==========
对于正要去做的事情,一旦我们怎么都想不出一个适合它的名字,往往就会幡然醒悟,意识到这件事情其实毫无意义。
==========
之间。使用一个专门类型,可以将函数的期望文档化。
==========
我们应力求代码清晰,但品牌是完全不同的事情。 有一个悠久的传统,项目和项目团队应该有个朦胧的、“聪明的”名字——宝可梦,漫威超级英雄,可爱的小动物,指环王中的角色,只要你能想得到。
==========
在计算机科学中只有两件难事:缓存失效和命名。
==========
重要的是,团队中的每个人都知道这些词的意思,并始终如一地使用它们。
==========
另一种方法是使用项目术语表,列出对团队有特殊意义的术语。这是一个非正式的文档,可以在 wiki 上创建并维护,也可以将索引卡片挂在墙上。
==========
实际上,尽量要在开始之前就理解整个问题。 但那不是现实的世界。现实世界是混乱的、矛盾的、未知的。在现实世界中,得到任何事物的精确规范,即使不是完全不可能,也是非常罕见
==========
我们的工作是帮助人们了解他们想要什么。事实上,这可能是我们最有价值的属性,
==========
最初对需求的声明,往往并非绝对化的要求。客户可能没有意识到这一点,但一定希望你能一起去探索。
==========
这就是我们所做的。当某些事情看起来很简单的时候,我们却会去寻找那些边缘情况,并就其不胜其烦地问人。
==========
这就开启了探索过程。你充当的角色是解释客户所说的话,并向他们反馈其中的含义。这既是一个演绎性过程,又是一个创造性过程:你会灵机一动,为一个更好的解决方案添砖加瓦,最终方案会比你或客户单独提出的方案更好。 需求是一个过程 在前
==========
在了解系统真实使用方式的同时,你还会惊讶于一个小小请求的实际效果——“你工作的时候我可以在旁边坐
==========
但这并不意味着,你可以不记录对客户需求的理解就扬长而去。这只是意味着,这些文档不必交付:它们不是需要交给客户签字的东西;相反,只是帮助指导实现过程的路标。
==========
他们可能会读最开始的几个段落(这就是为什么前两个段落总是要放执行摘要),
==========
我们喜欢可以写在真实(或虚拟)索引卡上的东西。这些简短的描述通常被称为用户故事。它们从使用某功能的用户角度,描述了应用程序的一小部分应该做什么。
==========
好的需求是抽象的。
==========
维护一张术语表
==========
如果你就是不愿意让这个问题搁置一段时间,那么最好的办法就是找个人去解释一下这个问题。通常情况下,围绕它的简单谈论就可以让你分心,从而得到启迪。
==========
· 个体和互动高于流程和工具 · 工作的软件高于详尽的文档 · 客户合作高于合同谈判 · 响应变化高于遵循计划
==========
质量只能来自团队每个成员的独立贡献。质量是内在的,无法额外保证。
==========
自动化是每个项目团队的基本组成部分。确保团队拥有构建工具的技能,以便可以构建和部署工具,用其来将项目开发和生产部署自动化。
==========
即使你碰巧命中了代码的每一行,也不代表全部。重要的是程序可能具有的状态数。
==========
一个 Bug一旦被人类测试员发现,这就应该是它被该人类测试员发现的最后一次。要立即修改自动化测试,以便这个特定的 Bug,从此往后每次都被检查到——不能有任何例外,无论它多么琐碎,也无论开发者有多少抱怨,或是不停唠叨“哦,永远不会再发生了”。
==========
用户真正要的不是代码,他们只是遇到某个业务问题,需要在目标和预算范围内解决。他们的信念是,通过与你的团队合作,能够做到这一点。
==========
但是真正有意义的是这些对业务价值的期望,而不仅仅是软件项目本身。
==========
而事实上这个头衔应该是“解决问题的人”。这就是我们所做的,也是一个务实的程序员的本质。 我们在解决问题。
==========
我们想看到你对所有权引以为豪——“这是我写的,我与我的作品同在”。你的签名应该被认为是质量的标志。
==========
说明 · · · · · ·
表示其中内容是对原文的摘抄