高效程序员的45个习惯

持续、小步前进才是敏捷!——>开发轻松、快速;

 

编程思想和代码结构

 

持续反馈+报告

 

先稳定再改良

 

每个迭代结束后,回顾:哪里做的好,哪里需要改进。

 

以身作则

 

小而可达到的目标会让人全速前进。

在团队中,修改东西必须很谨慎,要时刻警惕风险。 

保证系统稳定。

先构建系统最初的、小的和有用的部分。挑选一系列小的功能,完成第一次交付。——客户承担的风险更低

做一个大致的评估,给出误差范围,解释如何才能达到这个目标

将精力集中于一点 

挑战陌生的领域

基础的重要性

好书让你系统的学习技术

抓紧时间

优秀的程序是不断重构的过程。

通过与人交流来锻炼自己的思维

学习是保证你以后路越走越宽的最佳手段

依赖于单元测试。但价值不大的方法,不值得花费时间进行测试。单元测试只有在达到一定测试覆盖率时才能真正发挥作用

若不是真正需要它时,就不应该实现这个功能

消除还没有编写的类,会简化代码;

任何一个设计都可以被改进。

实现特定功能的最低成本。 

不同环境,就会有不同问题

硬件比开发人员的时间便宜。要在多个平台上测试,只要为每个平台设置持续集成系统就行了。 

软件在不同平台上出现bug很可能是因为栈布局的差异机器字大小端的不同所致。 

现在对你显而易见的事,对别人可能并非如此。注释要说明为什么会这样写代码

细心选择有意义的命名

性能、成本、上市时间等,再软件开发过程中都是至关重要的因素。若对任何单个因素独断强调,而不考虑其他因素,必然导致灾难。 

没有适合所有状况的最佳解决方案。必须对问题进行评估,选出最合适的解决方案。每个设计都是针对特定问题的。 

粒度如果太细,也会失去实用价值。

面向对象的代码让别的对象去做事情不要抢别的对象或组件的工作。告诉它做什么

针对is-a关系使用继承;针对has-auses-a关系使用组合。 

通过替换代码来扩展系统通过替换遵循接口契约的类,来添加并改进功能特性

不要试图马上了解系统的所有细节。若能隔离出发生问题的模块,就更容易修复发生问题的代码。

识别复杂问题的第一步,是将它们分离出来。只与最小数量的相关代码发生关系,就可以更快发现问题的根源所在。

让代码可以测试!——>这样代码自然职责单一,耦合性低,可维护性高。 

在解决问题时,要将问题域与其周边隔离开。

以二分查找的方式来定位问题。将问题空间分为两半,看看哪一半包含问题。再将包含问题的一半进行二分,并不断重复这个过程。

写代码时,要估计到会发生的问题。

处理或是向上传播所有的异常

记录运行时调试日志,当捕获或是抛出异常时,都要记录日志信息。这样做对以后的跟踪工作很有帮助。

在调用方法时,一定要注意此方法是否有抛出异常

代码刚开发完,是寻找问题的最佳时机。放任不管,它不会变得更好。

代码review,要寻找程序的bug,效果是任何已知形式测试的两倍,而且是移除80%bug的唯一已知方法

 

先写大的框架(即先定格局),然后再写细节。在很短的编辑——构建——测试循环中编写代码

 

编写代码时,每天付出一点小的努力,避免代码腐烂,保证应用程序不会变得难以理解和维护

 

先做好设计,想清楚问题,再开始编码。 设计及其代码实现会不停地发展和变化。设计满足实现即可,不必过于详细

 

在理解一个问题时,需要渐次的问5个以上的“为什么”

不停问为什么。不能只满足于别人告诉你的表面现象。要不停提问到你明白问题的根源

我不知道是一个好的起点。应由此进行更进一步的调查。

在问“为什么”前,想好你提问的理由,这会有助于你问出恰当的问题。

 

若你自己都不清楚所谈论的东西,就根本不可能精确描述它。

 

原则:

a、不管路走了多远,错了就要重新返回

b、态度+习惯+平衡;

c、起步才能变得很出色

d、设定最终期限——没有最好的方案,只有更合适的方案

e、结果最重要

f、设计充满了妥协

g、不仅要发现问题,更重要的是去解决它

h、只有一个人会为你负责——你自己。能否跟上变化,完全取决于你自己。

i、唯有变化是永恒的

j、当必须要把工作切换到一种新的技术领域,你能做到!

k、不可能精通每一项技术。只要你在某些方面成为专家,就能使用同样的方法,很容易成为新领域的专家。

l、要明白为什么需要这项新技术——它解决了什么样的问题?它可以被用在什么地方

m、总是要成为你所在的那个对中最差的。若你是最好的,就需要重新选择队了。

n、为了解决问题,需要很好的了解系统的全局。需要查看所有你认为和问题相关的部分——即便其他人觉得这并不相关。

o、计划是没有价值的,但计划的过程是必不可少的。

p、若目标很遥远,就很难让自己专注它

q、最终期限会迫使你做艰难地决定。

r、一步行动,胜过千万专家的意见

s、平衡以得到最佳的决策:

t、要经常提醒自己是否有方法写出更易于理解的代码

u、代码要清晰表达意图——>可读

v、让团队其他人读自己一年前写的代码,是否可以读一遍就知道它的运行机制

w、真正的高性能系统,从一开始设计就在向这个方向努力

x、开发的代码必须即时反馈

y、保持系统灵活性的关键方式,是当新代码取代原有代码之后,其他已有的代码不会意识到任何差别

z、单元测试强迫对代码分层。因为要保证代码的可测试,就必须把它从周边的代码中解脱出来。

 

每个类按照下面的术语描述:

类名:

职责:它应该做什么?

协作者:要完成工作它要与其他什么对象一起工作? 

 

高效程序员:

第一:激情,就是对你的工作感兴趣.

第二:有很强的分析能力.

第三:高质量的编码.

第四:快速的解决程序的问题.

第五:发散思维.

第六:团队默契合作.

第七:相信总可以解决任何问题.

 

快速而可靠交付高质量软件

 

短迭代开发,得到反馈(迭代一般是两周的时间)、分解任务、站立会议、用户参与、测试驱动、持续集成、自动部署(一键安装)、定期回顾(持续改进)、持续学习

 

迭代:在小且重复的周期里,完成各种开发任务:分析、设计、实现、测试和获得反馈

通过反馈进行自我调整和完善。

 

白板、草图等都是非常好的设计工具复杂的建模工具只会让你分散精力,而不是启发你的工作。 

 

1、In Action

(1)态度:专业的态度;

项目需要什么你就做什么;

反馈是敏捷的基础;

 

出了问题,最高优先级应该是解决问题

若你没有犯过任何错误,就说明你可能没有努力工作。

 

探究问题的根源,想明白会产生什么其他影响

让团队成员花些时间阅读其他同事写的代码,能确保代码是可读和可理解的。

单元测试能帮助你自然地把代码分层,分层很多可管理的小块,这样就会得到设计更好、更清晰的代码。单元测试就是一份文档,让你理解代码。

 

也许不知道每块代码的每个细节,或者每个算法的每个步骤,但要对整体的相关知识有很好的了解,理解它是如何工作的

深入了解你正在开发的代码外,还需要从更高的层面了解大部分代码的功能,这样就可以理解系统各个功能块之间是如何交互的。

 

权衡观点本身的利弊,表达自己的观点。

 

融合各种不同的想法和观点,远远胜于单个想法为项目带来的价值。

  

评判那些场景发生的可能性有多大。 

用合适的词和理由去解释为什么你不赞同这个方案,并提出明确的问题

解释清楚自己的理由

 

业务领域的底层数据模型

 

代码令人费解,唯一的解决方法是重构代码

 

(2)学习

许多新技术都是基于现有的技术和思想。但会加入一些新的东西,这些新东西是逐步加入的。——要跟踪技术变化

 

有很多方法和工具可以帮助我们继续充电

a、迭代和增量式的学习

每天计划用一段时间来学习新技术,要经常进行。

记下你想学习的东西——听到一些不熟悉的术语或短语时,记下来,在计划的时间中去研究。

b、了解最新行情

阅读社区讨论,了解他人遇到的问题以及一些好的解决方案。

选择好的技术博客,去读读。(pragmaticprogrammer.com)

c、阅读

关于软件开发和非技术主题的好书。

 

不需要精通所有技术,但要清楚知道行业的动向,从而规划你的项目和职业生涯。

要正确把握自己投入的精力。许多新想法并没有成为有用的技术。

不要因为想学习而将应用切换到新的技术、框架或开发语言。必须先评估新技术的优势开发一个小的原型系统

 

学习新的技术和新的开发方法。举一反三,灵活应用。

现在开发者的时间才是最昂贵的资源。

 

学习一门新的语言,应该使用推荐的集成开发环境。对于所使用的语言,要总结熟悉的语言特性

 

对团队投资:给大家介绍一些概念,演示工具等,提供应用程序示例。

整个团队都要了解新技术,并如何使用它。讨论与应用相关的一般主题。

 

为了解决问题,你需要知道许多可能的影响因素

 

如何有效提问?

 

(3)编码——易于理解、扩展和维护。让代码简单。——>代码整洁、扩展性好

代码要有表达力——>做了什么;要经常提醒自己是否有方法写出更易于理解的代码。

增量式编程

注释是为了帮写得不好的代码补漏

把握开发节奏首先解决困难的问题,把简单的问题留到最后;防止所有事情同时发生

 

软件项目需要不停地前进,同时要清楚自己的真实进度。

确保每个迭代周期的时间相同

 

在每天结束时,测试代码,提交代码。

以固定、有规律的长度进行迭代。

当与其他团队合作时,需要减慢开发节奏。

 

对代码进行检查,防止它们变成庞然怪物。 

 

良好的面向对象设计原则建议

编写内聚的代码,保持逻辑清晰。通过设计能够根据契约进行替换,以保持代码的灵活性。

 

若没人理解一段代码的工作方式,这段代码没用!

 

代码清晰程度的优先级比执行效率高!因为阅读代码的次数要远远超过编写的次数。

 

首先理解代码做了什么,如何做的?然后,搞清楚将要改变哪些部分,最后开始修改并测试。

 

通过指定一个外部对象来进行同步操作

 

编写代码,要使用语言特性来提升表达力。使用方法名传达意图参数的命名要帮助读者理解背后的想法。

异常传达的信息是哪些可能会出问题,如何进行防御式编程,要正确使用和命名异常。好的编码规范可以让代码变得易于理解。

变量名清楚、逻辑分离清晰、表达式简洁 

 

方法要说明下列信息:

a、目的:做什么的;

b、前置条件:需要什么样的输入;

c、后置条件:有哪些返回值;

d、异常:会发生什么样的问题?会抛出什么异常?

 

性能、成本、便利性、上市时间等,再软件开发过程中都是至关重要的因素。若对任何单个因素独断强调,而不考虑其他因素,必然导致灾难。

降低开发成本和缩短上市时间,二者一样重要。

有的关注界面展示,有的关注性能,应咨询相关人员,让他们决定应将重点放在哪里

 

没有适合所有状况的最佳解决方案。必须对问题进行评估,选出最合适的解决方案。每个设计都是针对特定问题的。 

要确认投入是否有回报。

 

增量式开发——所开发的代码基于即时的反馈关键在于持续做一些细小而有用的事情,而不是做一段长时间的编程或重构。

在很短的编辑——构建——测试循环中编写代码。在代码没有得到即时反馈时,不会再继续编写代码

 

要经常重构测试。

 

保持简单:

开发人员应为自己能够创建出一个简单且可用的设计而骄傲

在用设计模式前,先问问自己,是不是特定的问题需要你使用这个解决方案。不要让自己进行过分设计。

简单不是业余、能力不足。

 

优雅的代码,一眼看上去就知道它的用处,而且很简洁

一个好的设计会让人觉得很舒服。若觉得什么地方不对,就好好想想是哪里出了问题。

 

开发可以工作的、最简单的解决方案——必须满足功能需求

编写的代码没有一行多余的。

代码总是可以得到进一步精炼,但到了某个点后,再做改进就不会带来任何实质性的好处了

 

内聚性用来评估一个组件(包、模块)中成员的功能相关性。内聚程度高,表示各个成员共同完成了一个功能特性或一组功能特性。

也要遵循内聚性。

职责单一——>内聚性一定高

 

粒度如果太细,也会失去实用价值

 

告知,不要询问——命令与查询相分离的模式,即将方法分为命令和查询两类。命令可能会改变对象的状态,有可能返回值。查询仅仅提供对象的状态,不会修改

面向对象的代码让别的对象去做事情。不要抢别的对象或组件的工作。告诉它做什么,然后盯着你自己的职责就好了

要保证查询没有副作用。 

 

根据契约进行替换:

保持系统灵活性的关键方式,是当新代码取代原有代码之后,其他已有的代码不会意识到任何差别。

 

Liskov替换原则:任何继承后得到的派生类对象,必须可以替换任何被使用的基类对象,而且使用者不必知道任何差异。即某段代码如果使用了基类中的方法,就必须能使用派生类的对象,并且自己不必进行任何修改。

 

当使用继承时,想想派生类是否可以替换基类。若不能,就要问问自己为什么要使用继承

 

 

如何让代码易于理解?——明白告诉阅读代码的人,代码做了什么

  

(4) 敏捷协作

准备好后再共享代码:提交的文件应该与一个特定的任务或一个bug解决相关。绝不要提交尚未完成的代码。应该频繁提交代码。

 

让团队中的成员一起朝着正确方向努力。

定期安排会面时间。面对面的会议是最有效的沟通方式。

实行代码集体所有制,以保证任何团队成员的缺席不会对项目造成影响。

团队中每个人都要提供技能,推进各自的职业发展。

允许大家自己想办法

和团队成员一起做代码review

及时通报进展与问题,让大家了解彼此的进度和遇到的问题。不要等着别人来问项目状态如何。

 

站立会议——保证会议快速进行;一般在大家到公司之后的半个小时到一个小时之内举行。最长不超过30分钟。

每个人回答三个问题:

a、昨天有什么收获?

b、今天计划要做哪些工作?

c、面临哪些障碍?

把要解决的问题记下来。

通过促进代码和思路的共享,来提升开发速度。

在会议中要给出具体的进度

 

一个设计要解决的是眼前面临的特定问题。随着设计的实现,对问题的理解也会发生改变。

在开始实现之前,就做出一个很有效的详细设计非常困难。因为没有足够的上下文,能得到的反馈非常少。

作为设计人员,若不能理解系统的具体细节,就不可能做出有效的设计。

 

新系统的设计者必须要亲自投入到实现中

架构师应指导开发团队,提升他们的水平,以解决更为复杂的问题。

程序员在拒绝设计的同时,也就放弃了思考。不要进行单独设计。

 

增强可逆性是注重实效的软件实现方式的关键构成部分

 

在团队中实现任务轮换制,让每个成员都可以接触到不同部分的代码,可以提升团队整体的知识和专业技能。

在试图理解代码时,要问些有用的问题,对问题领域深入理解。

 

共享知识,让团队的人变得更好。

好的想法不会因为被许多人了解而削弱。

当别人提出问题时,可以发现不同的角度。

遇到无法回答的问题,说明这个领域的知识不够完善,需要在这一方面进一步增强。

分享自己的知识、经验和体会。

指导别人,也是提升自己。

若一直在就同一个主题向不同的人反复阐述,不如就此主题写一篇文章或一本书。

 

告诉团队成员解决问题的方法,也要知道如何解决问题的思路

用问题来回答问题

 

代码刚开发完,是寻找问题的最佳时机。放任不管,它不会变得更好。

代码review,要寻找程序的bug,效果是任何已知形式测试的两倍,而且是移除80%bug的唯一已知方法。

在签入代码之前,有另一名开发人员对代码进行彻底的复查。

 

code review要检查的最基本的问题列表:

a、代码是否能被读懂和理解?

b、是否有明显的错误?

c、代码是否会对应用的其他部分产生不良影响;

d、是否存在重复的代码

e、是否存在可以改进或重构的部分?

 

复查所有的代码。要让不同的开发人员在每个任务完成后复查代码

 

code review要积极评估代码的设计清晰程度。

可以让某段代码明确变得更好

跟进给出的建议

 

有问题要趁早提出来,给机会让人找出解决方案;

及时

 

(5)反馈

如何获得反馈?如何更好控制团队进程和性能?

 

时间也是一个非常重要的反馈。——为任务设定一个最终期限

通过演示获得频繁反馈。增量发布来发布新功能。——要让客户感觉到在一定程度上控制项目的方向

 

给客户演示所完成功能的时间与得到客户需求的时间间隔越长,你就会离最初需求越来越远

对得到的反馈,如建议、bug修复、功能增强、变更要求等信息,要有一个跟踪系统记录这些信息。

 

人的本性——当开始使用新系统的部分功能时,才意识到它的影响和可能发生的问题

 

维护项目术语表——帮助你和用户进行沟通。在项目开发中,从术语表中为类、方法、变量选择合适的名字

 

确保代码不会变坏

设计良好的API

编写能产生反馈的代码——>单元测试,单元测试能确保你不破坏任何功能单元测试有用的设计工具单元测试是可靠的文档

语言都有对应的单元测试框架

 

确保测试可重复;

测试边界条件;

不要放过任何一个失败的测试;

 

先使用再实现: 

先写测试,你就会站在用户的角度来思考——>可以设计一个更好的接口,并能帮助你改进设计

 

好的设计不表示需要更多的类

添加无用代码总是不好的想法。

专注于设计接口

实现特定功能最低成本 

 

关键业务逻辑要独立测试

 

判断工作进度最好是看实际花费的时间而不是估计的时间。

在你最后真正完成一项任务时,要清楚知道完成这个任务真正花费的时间。 这样为下次评估作参考。

 

让下一步工作可见——待办事项。确定优先级。

评估那些需要完成的待办事项

 

关注功能,而不是日程表;

以一周作为时间单元,粒度太粗了。

 

倾听用户的声音:没有愚蠢的用户

系统要有详细的错误提示信息

要和真实用户进行交谈,耐心倾听。 

 

每一个抱怨的背后都隐藏了一个事实。找出背后真正的问题,解决问题

若代码问题解决不了,可以考虑通过修改文档或培训来弥补。

 

(6)调试

如何提高调试效率,节省开发时间?

 

要想有效重用你的知识,记录问题解决日志

报告所有的异常

在出错时,要考虑用户的感受,必须提供有用的错误信息。 ——提供更易于查找错误细节的方式。但不要让用户陷入其中。

 

编译警告就是错误。签入构建工具中的代码不应该产生任何警告信息。

在eclipse中,windows-preferences-java-compile-errors/warnings,修改警告的报告级别。

 

移除被弃用的方法

 

必须要处理所有的异常若可以,从失败中恢复最好,若不能处理,就要把异常传播给方法的调用者。

编程时,要想想出现问题时——即事情没有按计划进行时,会发生什么。

不是所有的问题都应该抛出异常。

决定由谁来负责处理异常是设计工作的一部分。

抛出的异常应该在代码的上下文中有实际意义。

记录运行时调试日志,当捕获或是抛出异常时,都要记录日志信息。这样做对以后的跟踪工作很有帮助。

 

没有人愿意调用抛出31种不同检查异常的方法。

 

程序使用时,仍然会发生很多的问题,如与数据库服务器之间的连接可能丢失等。

当发生问题时,让应用详细记录错误的相关数据

错误提示信息要易于理解,要有助于定位错误

 

当应用进入生产系统,就不能把一些底层错误信息(帮助开发人员错误定位的信息)直接暴露给用户了。 

错误报告、调试信息非常重要,不要轻易将其丢弃。因为有助于解决问题,当问题发生时,可以详细研究问题的细节描述和发生上下文。

 

没有必要等待抛出异常来发现问题。在代码关键点使用断言来保证一切正常当断言失败时,要提供与异常报告同样详细的信息。 

 

 

(7)交付用户想要的软件

创建符合用户需求的系统

 

最大的敌人是变化。

设计是软件开发的基础。

 

确保在项目中引入合适的技术。——在考虑引入新技术或框架之前,先要把你需要解决的问题找出来。

然后问自己:

这个技术框架能解决这个问题吗?——先做一个小的原型;

维护成本是多少?

 

不要开发你能下载到的东西,将更多精力放到具体应用的开发中。 

根据需要选择技术。对任何要使用的技术,多问一些挑剔的问题,并如实回答。

每一门技术都会有优点和缺点

 

保持项目随时可以发布——让项目一直处于可运行的稳定状态。

提交代码前,先本地测试,然后check out,最后check in。

 

代码集成是主要的风险。为了降低集成新代码带来的破坏性变化,需要提早集成、频繁集成

持续集成系统就是在后台不停检出、构建和测试代码的应用。

 

提早实现自动化部署。——要测试安装过程。

 

在设计方面,开发者做决定。但不要给业务上的关键问题做决定。

开发者及项目经理能做的一个最重要的决定就是:判断哪些是自己决定不了的,应该让用户决定

遇到一个问题,会影响到系统的行为或者如何使用系统,把这个问题告诉业务负责人。 

 

和客户讨论问题,要从业务的角度,介绍每种方案的优缺点,以及潜在的成本和利益。

 

记录客户做出的决定,并注明原因。

对于业务人员,若问题对业务没有影响,就是没有价值的。

 

实现代码时要考虑可能出现的变化

 

设计能帮助你理解系统的细节,理解部件和子系统之间的关系,并且指导你的实现。用UML画关键工作图必不可少,要使用类及其交互关系来描绘系统是如何组织的。

在做设计时,需要花时间去思考各种不同选择的缺陷和益处,以及如何做权衡。

 

好的设计?——若需求有了小的变化,它仍然容易去实现,那么就是好的设计。若小的需求变化就带来一大批基础代码的破坏,那么设计就需要改进。

好的设计应该是正确的,而不是精确的。它描述的一切必须是正确的,不应该涉及不确定或可能会发生变化的细节。

 

短迭代开发,增量发布

迭代:在小且重复的周期里,完成各种开发任务:分析、设计、实现、测试和获得反馈。

统一过程和敏捷方法都使用迭代和增量开发。 

 

大部分用户都是希望现在就有一个够用的软件。确定产品可用的核心功能,越早交到用户越好!不要为所有可能需要的华丽功能而分心,不要沉迷于你的想象,做一些华而不实的用户界面。

 

迭代不必紧挨着下一个迭代

 

大系统分解为一块块有用的小系统。

 

若发布的功能背离了用户的需要,多半是因为迭代的周期太长了!

 

业务应用

 

(8)

 

2、TIPS

(1)编码没有结束

重构:在功能不变的情况下,重新设计部分代码,改善代码质量。

 

(2)

 

3、PS

(1)敏捷工具箱

wiki:实现知识共享;

版本控制:项目开发中所有的产物——源代码、文档、构建脚步等都需要放入版本控制系统中;

单元测试:是开发者获得反馈的主要来源。

自动构建:又称为持续集成。构建是全自动化并可重复的。

 

(2)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值