编写高质量的代码,从命名入手

笔者从事开发多年,有这样一种感觉,查看一些开源项目,如Spring、Apache Common等源码是一件赏心悦目的事情,究其原因,无外两点:1)代码质量非常高;2)命名特别规范(这可能跟老外的英语水平有关)。

要写高质量的代码,不是一件容易的事,需要长年累月的锻炼,是一个量变到质变的过程,但要写好命名,只需要有比较好的英语语法基础和一种自我意识即可轻松达到。本博文将会结合本人的开发经验,总结出若干命名规则,这些命名规则纯属个人的使用习惯,不代表是一种理想的规则,在这里列举出来,供大家交流讨论。

1.切忌使用没有任何意义的英语字母进行命名

for(int i=0; i<10; i++) {
        ...
    }

这是在很多教Java基本语法的书上常见的代码片断,作为教学材料,这样写无可厚非,但作为真正的代码编写,程序员必须要养成良好的习惯,不要使用这种没有任何含义的命名方式,这里可以使用“index”。

2.切忌使用拼音,甚至是拼音首字母组合

cishu =5; // 循环的次数
zzje = 1000.00 // 转账金额

笔者在做代码检查的时候,无数次遇到过这样的命名,使人哭笑不得

3.要使用英文,而且要使用准确的英语,无论是拼写还是语法

  • 名词单数,必须使用单数英文,如Account、Customer。
  • 对于数组,列表等对象集合的命名,必须使用复数,而且最好按照英文的语法基础知识使用准确的复数形式,如 List<Account> accounts、Set<Strategy> strategies。
  • 对于boolean值的属性,很多开发人员习惯使用isXXX,如isClose(是否关闭),但这里有两点建议:1)最好不要带“is”,因为
    JavaBean的规范,为属性生成get/set方法的时候,会用“get/set/is”,上面的例子,生成get/set方法就会变成
    “getIsClose/isIsClose/getIsClose”,非常别扭;2)由于boolean值通常反映“是否”,所以准确的用法,应该是是
    用“形容词”,上面的例子,最终应该被改为
    closed,那么get/set方法就是“getClosed/isColsed/setClosed”,非常符合英语阅读习惯。

4.方法名的命名,需要使用“动宾结构短语”或“是动词+表语结构短语”

笔者曾看到过千奇百怪的方法命名,有些使用名词,有些甚至是“名词+动词”,而且,如果宾语是一个对象集合,还是最好使用复数:

createOrder(Order order) //good
orderCreate(Order order) //bad
removeOrders(List<Order> orders) //good
removeOrder(List<Order> order) //bad

5.对于常见的“增删改查”方法,命名最好要谨慎:

  • 增加:最常见使用create和add,但最好根据英语的语义进行区分,这有助于理解,create代表创建,add代表增加。比如,要创建一个

    Student,用createStudent要比用addStudent好,为什么?想想如果有个类叫Clazz(班级,避开Java关键字),现在要
    把一个Student加入到一个Clazz,Clazz很容易就定义了一个 addStudent(Student
    student)的方法,那么就比较容易混淆。

  • 修改:常见的有alter、update、modify,个人觉得modify最准确。
  • 查询:对于获取单个对象,可以用get或load,但个人建议用get,解释请见第7点的说明,对于不分条件列举,用list,对于有条件查询,
    用search(最好不要用find,find在英文了强调结果,是“找到”的意思,你提供一个“查询”方法,不保证输入的条件总能“找到”结果)。
  • 删除:常见的有delete和remove,但删除建议用delete,因为remove有“移除”的意思,参考Clazz的例子就可以理解,从班级移除一个学生,会用removeStudent。

6.宁愿方法名冗长,也不要使用让人费解的简写

笔者曾经遇到一个方法,判断“支付账户是否与收款账户相同”,结果我看到一个这样的命名:

checkIsOrderingAccCollAccSame(...) // 很难理解,我马上把它改为:
isOrderingAccountSameAsCollectionAccount(...) // 虽然有点长,但非常容易阅读,而且这种情况总是出现得比较少。

7.如果你在设计业务系统,最好不要使用技术化的术语去命名

笔者曾经工作的公司曾经制订这样的命名规则,接口必须要以“I”开头,数据传输对象必须以“DTO”作为后缀,数据访问对象必须以“DAO”作为后
缀,领域对象必须以“DO”作为后缀,我之所以不建议这种做法,是希望设计人员从一开始就引导开发人员,要从“业务”出发考虑问题,而不要从“技术”出
发。

所以,接口不需要非得以“I”开头,只要其实现类以“Impl”结尾即可(注:笔者认为接口是与细节无关的,与技术无关,但实现类是实现相关的,用

技术化术语无可口非),而数据传输对象,其实无非就是保存一个对象的信息,因此可以用“**Info”,如CustomerInfo,领域对象本身就是业
务的核心,所以还是以其真实名称出现,比如Account、Customer,至于“DAO”,这一个词来源于J2ee的设计模式,笔者在之前的项目使用“***Repository”命名,意味“***的仓库”,如AccountRepository.

关于“Repository”这个词的命名,是来源于Eric Evans的《Domain-Driven
Design》一书的仓库概念,Eric
Evans对Repository的概念定义是:领域对象的概念性集合,个人认为这个命名非常的贴切,它让程序员完全从技术的思维中摆脱出来,站在业务的

角度思考问题。说到这里,可能有人会反驳:像Spring、Hibernate这些优秀的框架,不是都在用“I”作为接口开头,用“DAO”来命名数据访
问对象吗?没错!但千万别忽略了语义的上下文,Spring、Hibernate框架都是纯技术框架,我这里所说的场景是设计业务系统。

8.成员变量不要重复类的名称

例如,很多人喜欢在Account对象的成员变量中使用accountId,accountNumber等命名,其实没有必要,想想成员变量不会鼓孤立的存在,你引用accountId,必须是account.accountId,用account.id已经足够清晰了。

“勿以善小而不为,勿以恶小而为之”、“细节决定成败”,有太多的名言告诉我们,要注重细节。一个优秀的程序员,必须要有坚实的基础,而对于命名规则这样容易掌握的基础,我们何不现行?

来源:51CTO

时间: 2024-10-03 22:48:36

编写高质量的代码,从命名入手的相关文章

编写高质量的代码—从命名入手(命名…

笔者从事开发多年,有这样一种感觉,查看一些开源项目,如spring.Apache Common等源码是一件赏心悦目的事情,究其原因,无外两点:1)代码质量非常高:2)命名特别规范(这可能跟老外的英语水平有关). 要写高质量的代码,不是一件容易的事,需要长年累月的锻炼,是一个量变到质变的过程,但要写好命名,只需要有比较好的英语语法基础和一种自我意识即可轻松达到.本博文将会结合本人的开发经验,总结出若干命名规则,这些命名规则纯属个人的使用习惯,不代表是一种理想的规则,在这里列举出来,供大家交流讨论.

如何编写高质量JS代码(续)_javascript技巧

继续上一篇文章<如何编写高质量JS代码>今次整理一下javascript函数知识点. 2.使用函数 函数给程序员提供了主要的抽象功能,又提供实现机制.函数可以独立实现其他语言中的多个不同的特性,例如,过程.方法.构造函数,甚至类或模块. 2.1 理解函数调用.方法调用以及构造函数调用之间的不同 针对面向对象编程,函数.方法和类的构造函数是三种不同的概念. 使用模式: 1,函数调用 复制代码 代码如下: function hello(username){     return "hel

深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点_javascript技巧

具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以帮助你写出更好的,更易于理解和维护的代码,这些代码在几个月或是几年之后再回过头看看也是会觉得很自豪的. 书写可维护的代码(Writing Maintainable Code ) 软件bug的修复是昂贵的,并且

编写高质量JavaScript代码的基本要点_javascript技巧

才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会是件很美妙的事情.具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以

《编写高质量Python代码的59个有效方法》——第8条:不要使用含有两个以上表达式的列表推导

第8条:不要使用含有两个以上表达式的列表推导除了基本的用法(参见本书第7条)之外,列表推导也支持多重循环.例如,要把矩阵(也就是包含列表的列表,即二维列表)简化成一维列表,使原来的每个单元格都成为新列表中的普通元素.这个功能采用包含两个for表达式的列表推导即可实现,这些for表达式会按照从左至右的顺序来评估. 上面这个例子简单易懂,这就是多重循环的合理用法.还有一种包含多重循环的合理用法,那就是根据输入列表来创建有两层深度的新列表.例如,我们要对二维矩阵中的每个单元格取平方,然后用这些平方值构

《编写高质量Python代码的59个有效方法》——第2条:遵循PEP 8风格指南

第2条:遵循PEP 8风格指南 <Python Enhancement Proposal #8>(8号Python增强提案)又叫PEP 8,它是针对Python代码格式而编订的风格指南.尽管可以在保证语法正确的前提下随意编写Python代码,但是,采用一致的风格来书写可以令代码更加易懂.更加易读.采用和其他Python程序员相同的风格来写代码,也可以使项目更利于多人协作.即便代码只会由你自己阅读,遵循这套风格也依然可以令后续的修改变得容易一些. PEP 8列出了许多细节,以描述如何撰写清晰的P

如何编写高质量JS代码_基础知识

想写出高效的javascript类库却无从下手: 尝试阅读别人的类库,却理解得似懂给懂: 打算好好钻研js高级函数,但权威书上的内容太零散, 即使记住"用法",但到要"用"的时候却没有想"法". 也许你和我一样,好像有一顾无形的力量约束着我们的计划,让我们一再认为知识面的局限性,致使我们原地踏步,难以向前跨越. 这段时间,各种作业.课程设计.实验报告,压力倍增.难得挤出一点点时间,绝不睡懒觉,整理总结往日所看的书,只为了可以离写自己的类库近一点.

《编写高质量Python代码的59个有效方法》——第3条:了解bytes、str与unicode的区别

第3条:了解bytes.str与unicode的区别 Python 3有两种表示字符序列的类型:bytes和str.前者的实例包含原始的8位值:后者的实例包含Unicode字符. Python 2也有两种表示字符序列的类型,分别叫做str和unicode.与Python 3不同的是,str的实例包含原始的8位值:而unicode的实例,则包含Unicode字符. 把Unicode字符表示为二进制数据(也就是原始8位值)有许多种办法.最常见的编码方式就是UTF-8.但是大家要记住,Python 3

《编写高质量Python代码的59个有效方法》——第15条:了解如何在闭包里使用外围作用域中的变量

第15条:了解如何在闭包里使用外围作用域中的变量 假如有一份列表,其中的元素都是数字,现在要对其排序,但排序时,要把出现在某个群组内的数字,放在群组外的那些数字之前.这种用法在绘制用户界面时候可能会遇到,我们可以用这个办法把重要的消息或意外的事件优先显示在其他内容前面. 实现该功能的一种常见做法,是在调用列表的sort方法时,把辅助函数传给key参数.这个辅助函数的返回值,将会用来确定列表中各元素的顺序.辅助函数可以判断受测元素是否处在重要群组中,并据此返回相应的排序关键字(sort key).