Johnny's Collections

生活总是有太多的无奈与失望,让我们以在努力学习和工作中获得的成就感和快乐来冲淡它们。

BlogJava 首页 新随笔 联系 聚合 管理
  10 Posts :: 0 Stories :: 80 Comments :: 0 Trackbacks
笔者从事开发多年,有这样一种感觉,查看一些开源项目,如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已经足够清晰了。

“勿以善小而不为,勿以恶小而为之”、“细节决定成败”,有太多的名言告诉我们,要注重细节。一个优秀的程序员,必须要有坚实的基础,而对于命名规则这样容易掌握的基础,我们何不现行?
posted on 2010-04-29 22:54 Johnny.Liang 阅读(6575) 评论(17)  编辑  收藏 所属分类: 编程技巧

Feedback

# re: 编写高质量的代码——从命名入手[未登录] 2010-04-30 10:35 m
第一个就写爆了……
for语句内使用i,j,k……是约定俗成的,符合习惯的。
并不是说教材上胡乱写的。  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-04-30 11:35 BioKen
第一个是有点牵强,可能他所举的例子不能表达的真正想要表达的意思吧@m
  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-04-30 11:52 泰妮丝童装
按开始的开始就爱看的  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-04-30 12:27 BearRui(AK-47)
其实一直有个想法困难很久,为什么不能使用拼音,大家都是中国人,英语水平参差不齐,但拼音水平还是一样的,而且用英文同1个意思,不同人写出来单词确不一样。我觉得使用拼音非常好,在注释比较少的情况下,拼音命名更能帮助理解程序。个人觉得拼音更加适合我们的国情。

当然如果非常常见的除外,比如add,insert delete。

如果你写的程序会给外国人看哪就另当别人认了。可是有几个人的代码会给外国人看?  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-04-30 12:45 Johnny.Liang
@BearRui(AK-47)
我是这样想的,做开发人员,基础英语知识是必备的工具,很多技术文档、规范、API都是英文的,即使有翻译,也是读英语的比较好,因此在我参与过的项目中,包括我曾经工作过的公司,都是严禁使用拼音的。  回复  更多评论
  

# re: 编写高质量的代码——从命名入手[未登录] 2010-05-01 19:56 海边沫沫
用拼音是真的不好,因为你不能把1234声注上去,而且即使注上去了,也有很多重复的词。用纯拼音写一本书你看不看?

用拼音的缩写就更加要人命了。

楼主的总结非常好,特别是对boolean变量的命名,让我很受启发。其它的条目我一般都是和楼主一样的做法。  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-05-02 11:10 vagrant
政府项目里面,无数的中国特色式业务名称,怎么翻译成英文?项目组一堆人,怎么确保同一个名称翻译成同一个英文单词?  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-05-04 18:21 sf
第一项就乱叫,请去看下linux 内核源码在来写blog, ok?  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-05-06 10:29 r
@vagrant
世事无绝对,楼主概括的是大部分的情况。顶楼主一个,辛苦!
  回复  更多评论
  

# re: 编写高质量的代码——从命名入手[未登录] 2010-05-07 17:41 Gavin
值得借鉴...  回复  更多评论
  

# re: 编写高质量的代码——从命名入手[未登录] 2010-05-21 09:28 Mike
写得不错,感谢楼主分享。 期待有更多高质量的文章可以学习。  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2010-06-20 15:22 赵云
第一项不敢恭维!  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2011-01-05 17:55 Xluo
赞一个,学习了。  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2012-10-15 22:17 eyougo
当你遇到
JYR
JYRQ
JYRS
YYRQ
YYR
这一长串变量命名在一个类里的时候,头疼不?
解释一下:
JYR借阅人
JYRQ借阅日期
JYRS借阅人数
YYRQ预约日期
YYR预约人
哈哈哈  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2014-06-30 12:57 dohkoos
第1点完全是谬论,约定俗成的东西你也要改。而且你以为人家不写成index是没有理由的吗??
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
}
}
算法里经常有这种代码,你把 j 这个变量改改看,脑细胞死一堆还可能找不到更好的命名。那些写程序的先驱几年几十年的血泪总结出来的东西啊。

为什么不可以在代码中使用拼音命名。代码可读性包含一致性,因为基础代码都是英文的,如果用拼音命名的话,就破坏了这点,破坏了代码的可读性。在读代码时需要频繁地在命名是拼音还是英文中切换,影响效率。
用首字母缩写??过段时间你自己还能记得它是什么意思??  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2015-05-28 18:15 会长
1,第一个是约定成俗了,而且我一直认为i是index的缩写;
2,拼音或汉字我觉得可以偶尔使用,有些词很难翻译,如”计划生育“、”改革开放“等;
3,接口I打头,抽象类Abs打头一目了然,”实现类以“Impl”结尾“,不也是从技术的角度出发的,如果实现类还实现了别的接口怎么办...
4,"成员变量不要重复类的名称",这样的话如果数据库中字段名称为XXXId,那么实体类属性名称与之对应比较好。当然数据库也可以不加XXX,直接上Id,但我觉得主键还是tableNameId比较好,否则在长SQL语句中到处都是Id,眼花缭乱。

其余部分严重同意。  回复  更多评论
  

# re: 编写高质量的代码——从命名入手 2015-05-28 18:18 会长
@BearRui(AK-47)
拼音的话会产生歧义。当然熟悉系统的人没事,新人就比较郁闷了,想砸键盘。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: