如何才能编写出优质代码,每个开发人员都有自己的理解。我大致整理了下面十八个招数,供大家参考。正像武学界的武功一样,每门功夫都需要一个名字,正好个人比较喜欢降龙十八掌,而正好也有十八招
第一招:养成一个好习惯
在我第一年工作的时候,我有幸加入了一个好团队,另外有一个很好的领导者。我至今记得他跟我们讲的第一句话:一个良好习惯的养成对你们以后的工作非常重要,当然它需要你从一开始就去培养,并且持之以恒,坚持不懈。而我们下面讲的很多内容,或者说绝大部分内容都可以算做这个好习惯中的一部分。
第二招:规范你的代码
没有规矩,不成方圆。代码遵循统一的格式规范,首先便于自己日后维护,其次便于移交他人。自己读起来清晰明朗,他人看起来整洁规范,这对一个项目团队,一个公司来说尤为重要。检查的方式也很简单,如果整个项目的代码最后看起来是同一个人的风格,那么证明你遵循了规范。就好比我们读书年代的考试,你的考卷整洁清晰,肯定会给你附加分。这里我们举个例子来说:如何规范一个类中代码。首先成员变量的定义需要放在一起,不能几个在上面,几个在中间,几个又跑到下面去;接着是类中方法定义;最后是成员变量的get/set方法。同时,可以继续按照public、protected、private3种来细分。
第三招:合理注释你的代码
很多人写代码不喜欢注释,或者觉得项目时间紧,忙于实现了交差,或者觉得没有必要,反正可以看懂。
另外一部分人喜欢程序写完后再来注释,有点补交作业的概念。
只有少部分人会在代码开始之前,进行思路整理,写出代码逻辑各步骤,各分支的注释,然后在注释下面填充实现代码。
显然,第三种才是最正确的做法,正所谓:兵马未动,粮草先行。当然也是最难的,但是你只要习惯了,它也就soso了。
一份合格的代码的注释率一般在30%以上。
第四招:不写重复代码
我想我们每个开发人员应该把它当成孙悟空的紧箍咒,时时刻刻都要念上几遍来反复提醒自己。重复代码绝对是垃圾代码的第一特征,并且是最大的特征。Copy的时候会很爽,但往往有乐极生悲的时候,一旦出错,意味着加倍的工作量和持续的不可控。
不写重复代码的最高目标是不写两行一摸一样的代码,当然这仅存在理论的可能,我们仅需要做到不写两份功能一致或相似的代码即可。这个度我想你可以掌握。
第五招:不写过多参数方法
当你的方法参数超过5个时,你就要考虑你这个方法设计的是否合理了。真的需要这么多参数吗?是否可以精简?如果实在必须,那么你也是到了必须改变的时候,封装对象来进行传递吧,这样不仅减少了参数个数,也为以后提供了无穷扩展的可能。同时使用者也不必去硬记参数的顺序。
第六招:不做脱裤子放屁的事
脱裤子放屁是一件无意义的事,我想不会有人去做这样的事吧。我们编码的时候,也是如此,没有意义的代码就不需要写了。
我们开发的时候,常常会通过copy来实现一些功能,但是copy过来后,会引入很多使用不到的东西,这些代码搁置在那边完全就是无意义的,可以删除。
另外我们经常会不经意的犯一些这样的错误:写if else if else 判断语句的时候,条件判断会出现重复,分支里面的代码可能永远不会执行等,这些其实都是我们在码之前没有理清思路导致的,也就是我们前面所说代码注释的重要性了。
过多的考虑将来的可能性:有的时候我们考虑代码的可扩展性时,会进入一个误区,也就是过犹不及的概念。带入了非常多当前并没有出现的可能性,这些内容可能永远不会用到,完全没必要在当前就写进去。
第七招:限制好你的阀门
开闸放水,关门放狗,讲究的是一个入和出,写代码也一样。
小的来说,我们的方法,入参的考虑需要够讲究,够精细;出参的位置需要限制到方法的尾部。很多人喜欢在方法的中间用return来终止方法的运行。比如做一些check的时候,不满足就return,这不是一个好的做法,虽然执行上面并没有什么问题,但保证统一出口更重要。
比如你需要记录执行日志,或者在方法出口时需要做一些额外的事情时,那么统一出口会很方便,否则你需要在每个return处去处理。
大的来说,我们开放给外部使用的接口,是否被限制在了一个层面上。这个时候用代理模式、门面模式会是一个比较好的做法。过多的特性开放给外部时,有时候反而会让人不易掌握。用代理做一层封装,再统一门面后,会使得代码出入口更可控。
第八招:正确摆放你的代码
有的人说:啊哈,我学了core Java,我会了所有的基础,我可以去代码的世界自由遨游了。这话不能说它错,但如果你仅仅考虑就实现功能去做事的话,那就跟垒砖是一样的了。怪不得我们程序员常常会==泥水匠。其实你除了要实现功能外,你还要考虑的事情非常多,正确摆放你的代码位置就很重要。检查你的方法,看里面的实现逻辑是否应该放在这个名称的方法中;检查你的类,看里面的方法是否应该放在当前类中;检查你的工程,看里面的类是否应该放在这个工程里面。一层层检查,你该发现你的代码有多少问题了吧。这有时候就是人的过程性思维导致的,从大的方面来讲是我们抽象的不够。
第九招:多为你的使用者考虑
做任何事情如果没有服务的对象,也就失去了它本身的意义,同样的编码也是如此。或者你是做框架做产品的,那么你面对的就是普通开发人员,或者你是做项目的,那么你面对的就是我们通常意义上的客户。不管你面对的是什么对象,一个好的出发点非常重要:多为你的使用者考虑,也就说我们常说的,客户至上。这里我们拿编写工具方法为例:当你写出一个非常好的工具组件,最后你要考虑的肯定是开放的api接口,该开放哪些接口,接口的参数如何。这些都需要你从使用者的角度出发,你才能考虑的尽可能完善。不管是java里面的重载,亦或是设计模式里面的适配器,说的都是这个概念,为的都是让你的使用者尽可能的简单,少做事情。
第十招:加强你的理解能力
十几年的语文学习,不知道对你如今的工作有多大影响。在我看来,最大的作用就是培养了我们的理解能力。理解能力对于开发人员来说非常重要:
快速理解客户意思,能够保障你良好沟通进行
正确理解需求,能够保障你方向的正确性
同样的,优秀的理解能力能够使你轻易读懂他人代码。
第十一招:设计模式
设计模式的出现,是为了解决一些通用问题的套路,它能使你的代码更加优美、高效。23种设计模式,更多的是一种概念思想。我们学的时候可以从简单易用,且常用的一些出发。比如工厂、单例,逐渐的我们可以尝试代理、适配器、合成、门面,最后我们可以运用一些较复杂的观察者等。为了可以更好的理解,当你学完全部的之后,你可以去学习下反设计模式,它会让你选取设计模式应用场景的时候更加的契合,合理。
第十二招:拆卸你的代码
在我工作了5年之后,我终于明白,评价一份代码的优劣,其中一个非常重要的指标就是:是否易于拆卸。简单来说,就是它的耦合性。这里的耦合分为内耦合和外耦合。我们一般注意到的是外耦合,即我们的代码与外部代码之间。其实内耦合在某些时候更加的重要:我们的代码内部之间的关系。比如你做了一个持久化服务工具,里面涵盖了3块内容:增删改查、脚本操作、数据定义。整个持久化服务不依赖于外部的任何内容,或者依赖的层面会切割到一条线上,那么代表你这份代码的外耦合控制的非常好。这个时候我们有个同事想用到一个数据定义的功能,但是它想在里面加入非常多的个性化,也就是说他仅仅想要1/3的内容,这个时候你的代码如果能够很好的拆卸出来,而不破坏其他部分的平衡,你的内耦合才算达标。
第十三招:检查工具帮你忙
码完代码后,用上一些简单的静态检查工具,比如checkstyle、fingbug等,可以很方便的检查出你代码中格式、以及一些隐藏的漏洞。
另外可以做下单元测试,让你的代码更健壮。
第十四招:温故而知新
个人认为最好的一招,每隔一段时间,多回过头去看看你之前写的代码,可以一周,一个月。要把你写的代码当作自己的孩子一样去呵护,如果你还没有孩子,那当成男女朋友吧,或者小伙伴吧。简而言之,我们要对它充满感情,代码其实也是有生命力的。一份好的代码或许会存活很长时间,一年、两年、十年。但是一份糟粕估计很快就会被推翻重构。每次回顾你应该都可以找出你代码中的一些问题,这样逐渐的你们2人都在不断成长。
第十五招:学会站在巨人肩膀
有时候很多功能,度娘和google神器都可以帮你轻易的解决,所以完全没有必要自己绞尽脑汁,重起炉灶。因为已经有巨人助你攀登的更高了,为什么不享用呢。但是你会正确使用这个巨人吗?你是否是copy过来之后不加理解就进行使用呢?过后遇到问题束手无策。
因为我是做框架的,所以我遇到这类的问题会比较多。因为常常有人向我抱怨更新框架的复杂与风险,因为更新之后会出现各种问题。其实这些有两方面的原因:一是框架发布的时候本身存在一些问题;另外就是我们使用框架的方式并不正确。
正确踏上巨人肩膀首先你应该做到如下几件事情:
- 对你所用的内容熟悉,这是最起码的。比如你用到了哪些内容,这些都需要了如指掌。
- 最好能够将你应用的层面做下限制,也就是我们上面讲到的阀门的另一种情况了。比如你应用了一个第三方的功能,那么接入你的项目时,你是直接写到你的业务处理代码中,还是说会对其做一次封装呢?显然后者是一种正确的做法。虽然会耗费你一些额外的时间,但是不仅能够提高重用,而且一旦以后实现方式或者版本做升级,你需要付出的就会大大减少了。
- 正确把握个性化的度
有时候你需要用到框架某个功能,但是却有很多不满足,这个时候一般会考虑进行个性化代码实现。一般的做法都是简单粗暴型:copy出原代码进行修改。
其实好的一个做法是要先进行考虑,这个个性化的内容是否是框架原有功能的补充和完善,如果是,那么应该是提交框架去解决;或者自己实现了提交框架去集成然后供其他项目复用,也就是说该功能隶属原功能。
第二个做法是考虑在原有功能做一些扩展修改来支持:比如加上一些反射外调接口处理。这样个性化业务的内容还是自己搞,但是隶属框架的原功能都可以进行复用。
第三个做法是进行继承,原理和第二个一样。
最后才是考虑copy代码来进行修改。
基于原功能来做,最大的好处就是原功能一旦做优化和升级,那么你的这块内容将无缝得到升级。否则将来如果你想走回来,花的代价将非常大。
第十六招:开始砍你的代码吧
当我们还在呼哧呼哧为了实现一些新功能编写大量代码的时候,很多大牛的做法却与你截然相反,他们在不停的砍削原有代码,有的时候他们可以依靠精简代码来实现新需求。砍代码的另一个叫法是重构。
第十七招:一份详尽优美的指南
春秋的时候,有很多的说客,光凭三寸不烂之舌就可以攻城略地,退兵攘敌,可见说出来的重要性。所以不仅要实干,还需要能够将你做的内容展示出来。作为一个编码的程序员,更多可能就要靠写了,这个写一般就是一份指南,说白了就是一份文档。大到整个系统的操作手册,小到功能模块的api。就像市场营销一样,你需要把你做的东西推荐出去,让大家意识到这个东西的价值,好处,才会有人来买单。
所以,加强你的文档能力吧,骚年。
第十八招:无招胜有招
看过武状元苏乞儿的都知道,最后周星驰跌倒在地,观看降龙十八掌秘籍,风吹卷动,最终前面十七招融合就成了第十八掌:神龙摆尾。我们的编码也是如此,当你能够将所有东西都融会贯通后,你也就不需要去拘泥那么多的套路了,因为你本身已经习惯成自然,你的一举一动都已经是非常好的招式了。当然,对于这种境界,我还一直在路上。