• 代码整洁之道——命名与函数


    • 有意义的命名
    做有意义的区分
    • 不要以数字系列命名    没有提供导向作者意图的线索。如
      public void copyChars(char a1[], char a2[])

    如果将参数名改成source和destination,就会像样许多。

    • 不要使用有相同意义的名字    如ProductInfo和ProductData类,很难区分两者的区别。

    使用读得出来的可搜索的名称

      • 尽量不要使用单字母名称和数字常量    如果要搜索一个数字或一个字母往往很难。长名字胜于短名字。
    • 函数
    短小
    • 短小再短小    函数不应该有100行那么长,20行封顶最佳。
    • 代码块和缩进    if语句、else语句、while语句等,其中的代码应该只有一行,就是一个函数调用语句。这样既保持了代码的短小,也使函数更易于阅读和理解。

    只做一件事

    • 如果函数只是做了该函数下的同一抽象层上的步骤,则函数只做了一件事
    • 或者看函数能否再拆出一个函数,该函数是其下一抽象层的实现。
    • 每个函数一个抽象层级   这是让代码读起来像是自顶向下的段落的有效方法。

    函数参数

    • 最理想的参数数量是0,越多越不好    从测试的角度看,参数的增加将使测试用例指数性增长。
    • 一元函数的普遍形式    有两个极普遍的理由要向一个函数传单个参数。1,询问形式:想询问关于那个参数的问题,如boolean fileExits("Myfile")这样的; 2,转换形式:想要操作该参数,将其转换成什么,再输出之,如InputStream fileOpen("Myfile")这样的,把string类型的文件名转换为InputStream类型的返回值。
    • 二元函数    二元函数普遍比一元函数难懂。有些情况下使用二元函数是更好的,如定义一个点Point p = new Point(0, 0)。但对于如assertEquals(expected, actual)这样的二元函数,因为它没有自然顺序所以经常会搞错两者的位置。因此,我们应该尽量利用一些机制将其转换成一元函数。例如,写成expected.assertEquals(actual)。
    • 三个及以上参数    此时你应该想想其中一些参数是不是可以封装成类了。
    • 函数的名字   要给函数其个好名字,能够较好地解释函数的意图,以及参数的顺序和意义。对于一元函数和其参数应当使用非常良好的动词/名词对的形式。如write(name)就相当令人认同。更好的名称是writeField(name),它可以告诉人们"name"是一个"field"。    此外,我们还可以利用函数的关键字形式,即把参数名称加入到函数名中,如assertEquals改成assertExpectedEqualsActual(expected, actual)会好一些,减轻了记忆的负担。
    • 避免使用输出参数    如果函数要修改某种状态,应去修改所属对象的状态。

    使用异常替代返回错误码

    • 返回错误代码往往是在if语句中使用的,这可能会导致更深层次的嵌套结构。当返回错误代码是,就是要求调用这立刻处理错误。例如:
      if (deletPage(page) == E_OK) {
          if (registry.deleteReference(page.name) == E_OK) { 
              if (...) {}
              else{}
         } else {
              logger.log();
         }
      }
      另一方面,如果使用异常替代返回错误值,错误处理就能从主代码中分离出来。
      try{
          ......
      } 
      catch (Exception e){
          logger.log();
      }
    • 抽离try/catch代码块    try/catch代码往往会搞乱了代码结构,最好把它们从主体代码中抽离出来,另外形成函数。
      public void delete(Page page) {
          try {
              deletePageAndAllReferences(page);
          }
          catch (Exception e) {
              logError(e);
          }
      }
      
      private void deletePageAndAllreference(Page page) throws Exception {
          deletePage(page);
          registry.deleteReference(page.name);
      }
      
      private void logError (Exception e) {
          logger.log(e.getMessage());
      }
      上例中,我们将try/catch代码块独立放到了delete函数中,然后又在try里调用正常流程的代码,在catch里调用处理错误的函数,这样美妙的区隔,delete函数就可以很容易理解并且忽略掉了,代码也更容易管理和修改。
    • 错误处理就是一件事     错误处理函数不应该再做其他事,这就意味着,如果try在某个函数中存在,它就应该是该函数的第一个单词,而catch代码块后面也不该再有其他内容,即“前无古人,后无来者”。
    总结:大师级的程序员把系统当成故事来讲,而不是程序来写。永远别忘记,真正的目标在于讲述系统的故事,而你的代码(或函数)必须干净利落地拼装到一起,帮助你讲故事~~
  • 相关阅读:
    ios存储 plist 偏好设置 自定义对象存储
    Spring中Bean的生命中期与InitializingBean和DisposableBean接口
    Spring中BeanPostProcessor
    cxf
    ios快捷键
    UIPickerView
    ios通知-kvo
    7.python 装饰器
    5.python内置函数
    4.python 深拷贝 浅拷贝 函数 匿名函数lambda
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6314775.html
Copyright © 2020-2023  润新知