如何写好高质量的可读代码

来源:互联网 发布:家具店 淘宝 如何经营 编辑:程序博客网 时间:2024/05/16 02:48

写干净整洁的代码

阅读代码,眼缘很重要。代码是程序员的脸,保持干净整洁。

  1. 记得格式化代码
    建议使用eclipse默认的就行,Ctrl+Shift+F。项目内部格式化风格一定要统一,否则svn很难track。鉴于Java开发库以及流行的开源框架都用Block起始大括号不换行风格,Google也如此规范,统一为这种风格。
  2. 去除没有用到的类引用
    纯粹是美观的考量。Google要求import语句里面不允许出现*,更不能引入没有用到的代码。Eclipse里面的快捷键是Ctrl+Shift+O,这个键还能帮忙导入用到的类。
  3. 删掉无用的老代码
    修改代码的时候,有些同学会把老的没有用的代码注释起来,像宝贝一样生怕弄丢,日积月累,注释的代码比有用的代码还多几倍,很难阅读和维护。请删掉它,备份的问题放心的交给SVN或Git。
  4. 删掉IDE帮忙自动生成的无用注释
    TODO Auto-generated method stud等等之流的,请删掉,不解释。
  5. 合理利用空行
    空行的唯一作用是分割逻辑代码,是阅读时候大脑的一个休息区。但是空行又是昂贵的,编辑器一页代码200行以内,使用空行太过奢侈的话,我就光阅读空行了。Google不鼓励多个空行,依我的观点,绝对不能有两个相联的空行,原因简单,浪费可耻,眼睛跳跃也累。当然也反对几十行代码没有一个空行,大脑得累死。总之,优美的代码一定合理的利用了空行,空行都用不好写不出优美的代码。
  6. 想办法把Warning干掉吧
    每一个Warning背后都有一个故事,泛型,未被使用的Class引用,未被使用的private方法,未被使用的field,class cast,序列化等等。搞懂一个Warning背后的故事,优雅的解决掉一个Warning,你就向高手迈进了一步。如果实在是搞不定,注释SuppressWarning能够暴力的帮助你。

高效运用注释

有人说注释和代码一样重要,我不太认同。简单优雅的代码比注释更直接易懂,注释会骗人,代码不会,注释不正确比没有注释糟糕很多很多,一大堆无用的注释浪费空间,浪费脑力,不如没有注释。一段关键的算法,一个场景的特殊处理,用简短的注释解释思路,这里注释对于后来的维护人员来说,比代码更加重要。接口的注释是使用接口人员的说明文档,对他们来说也比代码重要。如果一段代码需要你很多很多的注释才能解释清楚,那么请重写那段代码,直到简短注释甚至无需注释。

  1. 给别人调用的接口要注释清楚
    包括Interface、非Java Bean的public方法以及工具类里面的public static方法。关注做什么(不是怎么做),输入输出,特殊情况处理(比如null或不合法参数),异常情况。这种为块级(Block)注释,一般用/** comments */格式。
  2. 特殊的算法简洁清楚地注释
    特殊的算法体现的是作者当时解决问题的思路和算法,具有业务上或者算法上的特殊性,需要备注一下,以防忘记或者其他维护同事难以理解。通常用单行注释即可,特别长的用/* comments */ 格式。
  3. 具有特殊控制意义或者业务意义的变量简洁注释
    主要是帮助阅读代码的时候帮助理解。格式和第二条相同。
  4. 千万别在代码的各个角落留下您的大名或者Ticket单号
    关于名字,请在Class的注释里面加一个@author yourname。阅读代码的时候,只有遇到很烂或者很优雅的代码,我才会去关注作者是谁,通过Class里面的@Author和SVN抑或Git,很轻松的就知道代码出自谁的手。关注代码的时候实在是没有兴趣思考你是谁。至于Ticket单号,提交代码的时候注释就足够了,项目由代码构成,而非Ticket,需要追踪的时候SVN或Git都能够轻松地帮忙搞定。
  5. 块级元素里面慎用多行注释
    可以理解为方法内部慎用多行注释。方法内部应该Focus在代码的实现上,而不是实现的思路,思路请移到方法的注释里面。方法里面的注释应该关注在一些特殊情况处理,程序逻辑的跳转上面,一般单行注释足够胜任。如果方法内部要用大段的注释,还是那句话,请重写。

命名简洁一致

命名规范是代码规范的重要一环。总的原则是遵循惯例,简洁,团队甚至个人命名保持一致。

  1. 除了方法用动词,其它的都用名词命名
    项目名,包名,类名,变量名,参数名都用名词命名,方法用动词开始命名。
  2. 按照Java的惯例命名
    包名全小写,每一个文件夹用一个名词命名,注意有且一个词,且长度尽量短一些。类名标准的HelloWorld格式,有人问FBIHelloWorld好呢还是FbiHelloWorld好,我看着后者顺眼,你呢?普通变量,方法名,参数名一律helloWorld,hWorld可不可以?反射的时候有问题,也不好看,建议每一个单词至少两个字母。Final变量HELLO_WORLD,同样不解释。
  3. 简洁即美
    特别强调,简洁不是说鼓励简写,相反简写要慎用,最好团队内部达成共识。我说的简洁是指找那么一个贴切、简短的词或词组来命名。
  4. 命名规范在团队内部保持一致
    A君FBIHelloWorld,B君FbiHelloWorld,C君hWorld,甚至A君混合两种风格,整个项目会显得混乱,难以理解和维护。

理解Java几个基本的概念

一些Java的基本概念一定要吃透,否则很容易犯低级错误。

Exception

麻烦统计一下你们项目里面处理异常,简单地e.printStackTrace()个数,少不能说明你们项目代码质量一定很高,但太多了一定意味着你们的代码质量不咋地,如果这些烂代码由很多人提交,那更是悲剧。e.printStackTrace()只是把Exception toString(),然后输出到System.err,开发的时候控制台还能显示一下,生产环境到哪里去找。我觉得简单e.printStackTrace()和try catch之后什么都不干一样恶劣。想看报错信息?借助Log4j或者Logback记日志吧,既能开发的时候控制台看到,也能在生产时记录到文件系统。

  • 何时抛出异常
    不正常的场景出现,当前程序决定罢工,并可选择地携带一些错误信息告知调用者,小心,异常。如果你的程序就是最后一环,拜托,别抛了,选择更优雅的方式吧。
  • 何时处理异常
    确定你可以处理那样的异常,并且决定catch之后如何继续下面的操作。catch之后记录日志是标配。如果你开发GUI,你就是最后的消费者,必须处理异常。

Transaction

如果你开发的系统要求数据的完整性和准确性,请花些时间好好吃透Transaction。有一个业务Service A,分为两个子Service A1, A2。如果分别调用A1和A2,并放到两个Transaction里面,如果A1执行成功,A2失败并Rollback,请问发生了什么?Service的粒度划分和Transaction的使用非常的重要。

Thread

不懂或者半懂不懂千万别用多线程,要用就去好好的了解一下它。依我的理解,多线程仅用在两个地方,性能提升和响应式(Responsive)的GUI界面。

Access

两个字,要明确。类,构造函数,属性,方法的访问权限要明确。public, protected,package,private,四个级别,了解不难,用好要功力。有的不喜欢明确定义访问级别的朋友会辩解说,我看JDK里面有的属性或者方法就没有申明权限嘛,JDK的开发工程师也懒。哈哈,往后看看,大多会特别的注释说是package级别的,如果package关键字能够用来定义package权限,他们估计早用了,何必还多写那么些冗余的注释。interface里面不用明确申明public,因为默认就是public的,而且只能是public的。程序员太懒惰不好,太勤快了也不好,难当。

寻求更好的解决办法(Better Solution)

项目经理A或业务达人B跑过来,某客户有一个新的需求,请帮忙如此如此改一下系统,如此如此设计。假如你听话马上开始勤奋地敲代码,我觉得90%以上该方案都不是什么好方案。can work与work fine之间有着遥远的距离,改BUG,支持新需求绝对不仅仅是If Else那么简单。套用Linus大神的话,如果A君或者B君比你更了解你的系统,帮你设计由你实现,那么你就没有价值,实现的系统一定很烂,不如A君或者B君直接来实现。大神的徒弟不一定就是大神,传输大都有损耗。找出所谓需求背后的真正动机,结合当前的系统寻求更好的解决方案。何谓更好,各有各的看法,个人觉得,要保持架构风格的统一,要考虑未来类似需求的普适性,要简单准确有效。

0 0