zoukankan      html  css  js  c++  java
  • 小酌重构系列[18]——重命名

    概述

    代码是从命名开始的,我们给类、方法、变量和参数命名,我们也给解决方案、工程、目录命名。在编码时,除了应该遵守编程语言本身的命名规范外,我们应该提供好的命名。好的命名意味着良好的可读性,读你代码的人无需太多的注释,就能通过名称知道它是什么,它能做什么事儿,以及它应该怎么用。

    我们命名、命名,不断地命名。既然有这么多命名要做,我们不妨做好他。

    关于命名

    取名字的成本

    取个名字很简单,取个好的名字就不那么容易了。快速随意地取个名字,还不如花点时间取个好名字,因为好名字省下来的时间要比花掉的多。

    假设你在程序中使用了不好的命名,将来有人读到你的程序时,他人可能会难以理解,于是去询问你。由于时间有点久远了,你需要花时间回忆当时的场景和逻辑。也许你能想起来,也许你忘记了它的确切含义,以至于最终你给到他人的答复是模糊不清的。
    仔细算算吧,你们为了理解这些不好命名的含义,已经花了太多的时间了。

    好的命名的关键是有意义

    可以从以下几点出发,去取个有意义的名字。(以下内容,总结自《Clean code》)

    • 名副其实:名称本身应该告诉了你“它是谁?它是做什么的?它该怎么用”,如果名称需要注释来补充,则是名不副实的。
    • 避免误导:提防使用差异较小的名称,例如:你在ProductService中提供了3个方法,GetProducts,GetProductInfo和GetProductList。这3个名字可能是在不同场景下使用的,调用者要获取产品信息时,到底该用哪个名字呢?如果你通过注释来描述这3个方法的使用场景,那就是名不副实。
    • 做有意义的区分:如果缺少明确的约定,GetProducts,GetProductInfo和GetProductList是没有区别的。在程序中最好制定一个规则,例如通过“Get + 名词复数”的方式获取批量信息,那么在ProductService中就应该只能出现GetProducts方法。
    • 使用可搜索的名称:可搜索的名称,意味着在修改代码时,你可以通过全文搜索找到它们。例如:订单审批的状态,你通过1、2、3、4这些数字来表示,还不如通过NewCreated、Approving、Approved、Rejected来表示,它们既有实际意义,也更容易搜索。
    • 每个概念对应一个词:Fetch, Retrieve和Get都表示“获取”,如果你用这些词为同种方法命名,请取其一,并作为命名规则贯彻实行下去。
    • 添加有意义的语境:很少有名称是能自我说明的,你需要用良好命名的类、函数或命名空间来放置名称,给读者提供语境。如果没有这么做,则可以给名称添加前缀。假设你有firstName、lastName、street、houseNumber、state这些变量,当它们放一起的时候,很明确地构成了一个地址。但当你在某个方法中看到单独state变量时,state既能表示“状态”,又能表示“州”,你能推算出它的含义吗?你可以为变量添加前缀,addrFirstName, addrLastName和addrState等,这样就提供了明确且有意义的语境。

    以上这些point,是除了编程语言本身的命名规范之外,你需要额外考虑的。不好的命名能混淆程序员的认知,给开发带来很多困扰。好的命名也不是一刻就能实现的,有时候限于你对系统和业务的理解,你可能难以给定一个“精确”的名称,但随着你掌握更深的业务,那些不好的名称你应该再反复推敲并调整。

    示例

    前面讲了那么多关于“命名”的事儿,都是为本文要讲的重构策略“重命名”做铺垫。

    如果你使用Visual Studio开发程序,你可以借助一些工具来重命名,例如Resharper,这个工具还提供了良好的命名建议。

    重构前

    下面的代码为了描述员工的姓名和计算小时收入的方法。

    public abstract class Person
    {
        public string FN { get; set; }
    
        public decimal ClcHrlyPR()
        {
            // code to calculate hourly payrate
            return 0m;
        }
    }
    

    很显然,这段代码提供了难以理解的命名。

    重构后

    于是对这段代码做了3处重构:

    • 将Person类重命名为Employee。"Person"的含义太宽泛,"Employee"则能体现员工的概念。
    • 将FN属性重命名为FirstName。"FN"没有提供确切的语义,它是什么单词的缩写?是"File Number"(档案编号),还是Frost Nova(霜冻新星)?
    • 将ClcHrlyPR()方法重命名为CalculateHourlyPay()。"ClcHrlyPR()",如果没有注释,我们无从知道Clc、Hrly和PR所代表的含义。
    // Changed the class name to Employee
    public class Employee
    {
        public string FirstName { get; set; }
    
        public decimal CalculateHourlyPay()
        {
            // code to calculate hourly payrate
            return 0m;
        }
    }
    

    小结

    命名是程序员的基本功,很多程序员显然没有完全掌握这个基本功。如果你想成为一个优秀的程序员,良好的命名是必备的素质,它虽然不会体现出你会什么技术,但它会纵贯你整个编程生涯。
    做好编程,从命名开始。

  • 相关阅读:
    Linux 常用命令大全
    冒犯了,问大家一个问题,会linux的进来帮我解决一下
    Linux 软件安装
    Ubuntu 12.04出现“device not managed”错误
    Linux 系统下vi编辑器的使用方法(copy其他人网站的,留着自己查用的)
    tar的打包压缩与解压缩,并解压到指定的目录
    Ubuntu文件的复制、移动和删除命令
    当Ubuntu12.04 如何获取root权限
    windows是用vnc远程连接ubuntu的方法
    Ubuntu 12.04 在root登陆之后没有声音的解决方法
  • 原文地址:https://www.cnblogs.com/keepfool/p/5510803.html
Copyright © 2011-2022 走看看