如果汉语背后没有文化,文化背后没有思想,思想背后没有精神,光TMD编造老娘和乔布斯没有说过的话,那中国永远不会是一个伟大的国家。——撒切尔夫人

《代码整洁之道》读书笔记二

动词与关键字

给函数取个好名字,能较好地解释函数的意图,以及参数的顺序和意图。

  • 对于一元函数,函数和参数应当形成一种非常良好的动词/名词形式。

    // good
    write(name)
    // better
    // 更具体,它告诉我们,"name"是一个"field"
    writeField(name)
  • 函数名称的关键字(keyword)形式。使用这种形式,把参数的名称编码成了函数名

    // bad
    assertEqual(expected, actual);
    
    // good 
    // 这大大减轻了记忆参数顺序的负担
    assertExpectedEqualsActual(expected, actual);

函数

短小

  • 函数第一条规则是要短小。第二条规则不是要短小。越短小越好,20行封顶
  • ifelsewhile等语句,其中的代码应该只有一行。该行大抵应该是一个函数调用语句。因为块内的函数拥有较具体说明性的名称,从而增加了文档上的价值

只做一件事

确保函数不能被再拆分

参数

最理想的参数数量是零,其次是一,再次是二,应尽量避免三

  • 不要传递标识参数,标识参数大声宣布函数不是做一件事。如果标识为 true 将会这样,标识为 false 则会那样
  • 二元函数:有些时候两个参数正好。例如 Point p = new Point(0, 0);因为点天生拥有两个参数。但大多数情况下应该尽量利用一些机制将二元函数转换成一元函数。例如,把writeField 方法写成outputStream的成员之一

    // bad
    writeField(outputStream, name);
    // good
    outputStream.writeFiled(name);
  • 参数对象:如果函数看起来需要两个、三个、或三个以上参数,就说明其中一些应该封装为类了

    // bad
    Circle makeCircle(double x, double y, double, radius);
    // good
    Circle makeCircle(Point center, double radius);

    从参数封装成对象,从而减少参数数量,看起来像是在作弊,但实则并非如此。当一组参数被共同传递,就像上例中的x和y那样,往往就是该有自己名称的某个概念的一部分

无副作用

  • 确保函数功能就像函数名描述的一样,不要做函数名描述以外的事情。应该为起一个更能描述函数功能的函数名

    public UserValidator {
        private Cyptographer cyptographer;
        
        public boolean checkPassword(String userName, String password) {
            User user = UserGateway.findByName(userName);
            if(user != User.NULL) {
                String codePhrase = user.getPhraseEncodedByPassword();
                String phrase = cyptographer.decrypt(codePhrase, password);
                if("Valid Password".equals(phrase)) {
                    // 副作用在于对这个调用
                    // checkPassword函数,顾名思义,就是用来检查密码。该名称并未暗示它会
                    // 初始化该次会话。可以重命名为 checkPasswordAndIntializeSession
                    Session.initialize();
                    return true;
                }
            }
            return false;
        }
    }
  • 普通而言,应该避免使用输出参数,如果函数必须要修改某种状态,就修改所属对象的状态

     
    // bad
    // 读者会弄不清s是输入参数还是输出参数
    // 也会弄不清这函数是把s添加到什么东西后面,还是把什么东西添加到s后面
    appendFooter(s); 
    // 函数签名
    public void appendFooter(StringBuffer report){}
    
    // good
    report.appendFooter();

posted @   崤函隳  阅读(58)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-10-20 2020/10/20 刘一辰的JAVA随笔
点击右上角即可分享
微信分享提示