编写可读代码的艺术-从命名和注释开始

什么样的代码才是真正好的、整洁的代码?iteye.com上的文章很多:
Grady Booch,《面向对象分析与设计》作者:
引用
    • 整洁的代码是简单、直接的;
    • 整洁的代码,读起来像是一篇写得很好的散文;
    • 整洁的代码永远不会掩盖设计者的意图,而是具有少量的抽象和清晰的控制行。
Dave Thomas,OTI公司创始人,Eclipse战略教父:
引用
    • 整洁的代码可以被除了原作者之外的其他开发者阅读和改善;
    • 具备单元测试和验收测试;
    • 有一个有意义的名字;
    • 使用一种方式来做一件事情;
    • 最少的依赖,并明确定义;
    • 提供了一个清晰的、最小的API;
    • 应该根据语言特性,在代码中单独显示必要的信息,而不是所有的信息。
     
从他们的归纳中,可以看出真正好的代码都有一个共性,可读性。在《编写可读代码的艺术》这本书中,作者是这样定义可读性的:“代码的写法应当使用别人理解所需的时间最小化”。在这本书的指导下,从命名和注释开始在自己这几年写的代码中找出一些例子。希望自己以后在这些细节上引以为戒。
一.把信息封装到名字中,无论是类,方法或变量的命名

    1.选择专业的词,尽量避免模糊或意义太广

 public List<UserIp> select(String userId){
 }

      如果改成这样是不是更明确:

 public List<UserIp> queryUserIps(String userId){
  }
 


    2.避免泛泛的名字
        避免像tmp,i,j ,k这样泛泛的名字,比较常见循环中的 i,j,k.

        for (int j = 0; j < actionLogs.size(); j++) {
           ActionLog actionLog = actionLogs.get(j);
         }

 
    如果改成这样:

        for (int index = 0; index < actionLogs.size(); j++) {
           ActionLog actionLog = actionLogs.get(index);
         }

 

    3.用具体的名字代替抽象的名字
    在给变量,函数或者其它元素命名时,要把它描述的更具体而不是更抽象。

        /**
         * 刷新IP库
         */
        public void refreshData() ;

    如果改成这样:

      /**
         * 刷新IP库
         */
        public void refreshIpData() ;
 

   4.使用前缀或后缀来给名字附带更多信息
        对于像带单位的值均可以用后缀来附加更多信息
        常见的打印日志的代码:

         long startTime = System.currentTimeMillis();  
         if (logger.isInfoEnabled()) {
                        logger.info((System.currentTimeMillis() - startTime) + "ms,success!");
         }

 

     如果改成这样:

 long startMs = System.currentTimeMillis();  
         if (logger.isInfoEnabled()) {
                        logger.info((System.currentTimeMillis() -  startMs ) + "ms,success!");
         }
    

 

    5.决定名字的长度
    (1)在小的作用域里可以使用短的名字,丢掉没用的词。

   public static StrategyType convertToStrategyType(StrategyTypeDO strategyTypeDO) {
         }

 

       如果改成这样:

      public static StrategyType toStrategyType(StrategyTypeDO strategyTypeDO) {
         }

 
    6.给boolean命名
        通常来讲,加上is,has,can 或should这样的词,可以把布尔值变得更明确。
        如代码:

        boolean first = true;
                if(subConditions!=null&&subConditions.size()>0){
                    for (FactorCondition condition : subConditions) {
                        String template = generateCode(condition);
                        sbf.append((first ? "" : " || ") + "( " + template + " )");
       
                        if (first) {
                            first = false;
                        }
                    }
                }
 

    若改为:

           boolean isFirst = true;
            if(subConditions!=null&&subConditions.size()>0){
                for (FactorCondition condition : subConditions) {
                    String template = generateCode(condition);
                    sbf.append((isFirst ? "" : " || ") + "( " + template + " )");
   
                    if (isFirst) {
                        isFirst = false;
                    }
                }
            }

 

    7.与使用者的期望相匹配
        方法的名称要符合用户的期望,我们通常期望get()方法是轻量的方法。

public double getFPSecurityModelScore(Event event) {
            //这里省略
           }
 

        若改为:

 public double computeFPSecurityModelScore(Event event) {
            //这里省略
           }

 

二.代码风格与注释

      一致的风格要比“正确”的风格更重要,对于一个团队乃至一个公司,要采用一致的格式化模板。对于注释,一定不要为注释而注释,许多时候好代码>坏代码+注释,当你觉得要写很多注释时,也从侧面反映出你的代码或设计不太美妙。注释的目的就是尽量帮助读者了解和作者一样多。
   
       1.不要为了注释而注释

  /**
         * Getter method for property <tt>groupName</tt>.
         *
         * @return property value of groupName
         */
        public String getGroupName() {
            return groupName;
        }
   
        /**
         * Setter method for property <tt>groupName</tt>.
         *
         * @param groupName value to be assigned to property groupName
         */
        public void setGroupName(String groupName) {
            this.groupName = groupName;
        }

 

    当然,上面的的注释是由模板生成的,确有为了注释而注释之嫌。
   
    2.注释要记录你的思想.

      包括为什么代码写成这样而不哪样的内在理由。对于代码的缺陷或需要优化的地方可给予注释,对于常量,可记录常量背后的故事,为什么是这个值,如:

        /**
         * The load factor used when none specified in constructor.
         */
        static final float DEFAULT_LOAD_FACTOR = 0.75f;
 


   
    3.站在读者的立场上思考。

     为普通读者意料之外的行为加上注释,用注释来总结代码块或精确地描述函数的行为,使读者不致迷失在细节中。

三.细节决定成败,表面并非肤浅
    对于上面的每一个细节如果都能做的很好,这就为写好代码,写好可读代码,写好整洁代码迈出了第一步。

参考资料:《编写可读代码的艺术》

你可能感兴趣的:(代码)