Clean Code --如何写出整洁的代码(上)

我喜欢这样的代码:代码逻辑直接了当,几乎不会隐藏缺陷;代码的依赖关系非常简单,维护起来非常容易;有完善的错误异常处理逻辑;性能要足够好,以至于不会引诱别人做出一些没必要的调优。

       整洁的代码应该是除了自己之外,可以由其他的人轻易的阅读和扩展。应当有详尽的单元测试以及验收测试。有意义的命名,而且只提供一种而非多种做一件事的途径,拥有明确的定义和提供清晰、尽量少的API--公共的方法。


有意义的命名

      “命名”在软件中是随处可见的,我们给变量,方法、参数、类以及包命名。选个好名字需要花时间的,但是带来的好处也是显而易见的。选个好名字,做到名副其实,而且一旦发现更好的名称,立即换掉它。

      int d;//消逝的时间,以日记

      这里的 d 什么业没有说明,并没有引起对时间消失的感觉,没能计量的对象以及计量的单位友好的说明。

    选择本意的名称更让人理解和修改。

      以上的代码逻辑并不复杂,问题不在于代码的简介度,而是在于代码的复杂度,没有说明此方法要做什么事。此段函数要求我们去了解一下问题:theList中的元素是什么?theList零下标中的元素意义何在?值4的意义是什么?如何使用返回的列表?

      问题的答案并没有在上下文中体现出来,但是这是必须的。如果我们在开发扫雷游戏,此函数的目的获取已经被标记过得单元格。heList是扫雷面板的单元格集合,那就应该将其名称改为 gameBoard。盘面的每个单元都用一个二维数组表示,零下标是一种状态值,恰好值4表示该种状态为“已标记”,那么代码应该这样优化。



避免误导

   必须避免留下掩藏代码本意的错误线索,应当避免使用与本意相悖的词。

       别用 accountList 来指代一组账号,除非它真的是 List 类型。 List 在Java中有特殊的含义,如果包含这组账号的容器并非是List,就会给引起错误的判断。因此用 accountGroup 或者 bunchOfAccouns, 甚至使用 accounts 都要好很多。

      提防使用细微之处较小的名称。相区分模块之中某处的 EfficientHandingOfStringsController 和另外一处EfficientStorageOfStringsController,会话多少时间呢?以同样的方式拼写出同样的概览才是正确打开的方式,拼写前后不一致就是误导。避免使用“O”  和 “l”作为变量,这通常看起来像“0”和“1”


做有意义的区分

   让你的命名给读者提供导向作者意图的线索,做有意义的区分


该函数的目的在于将a1的字符数组中的值复制到字符数组a2当中,但是该方法签名并没体现这一点,通过方法签名无法得知是a1向a2复制还是s2向a1复制。如果把参数名改为 source 和 destination,这个函数就会整洁的多,这也符合“明确”、“清晰”的原则。

废话是另一种没有意义的区分。

      如果有一个定义机场信息的类 AirportInfo 或者 AirportData类,尽管他们的名称不同,意思却无差别。Info 和 Data 就像 a\an\the一样是意义含混的废话(注意,只要体现出有意义的区分,使用a和the这样的前缀就没有错)。

      变量 nameString 会比 name好吗? flightNo 会币 flight 好吗? id 会比 idNumber好吗?getSegments();  getSegmentList():  getSegmentInfo(); 程序员并不知道在何种情况下调用那个函数。

       如果缺少明确约定,变量 moneyAmount和money就没有区别,customerInfo和customer没有区别,acountData 和account没却别,theMessage  和 messge没区别,pnrNo 和 pnr 没有区别,flightNo 和 flight 没区别,officeNo 和 office 没区别。要区分名称,就要以读者能够鉴别不同之处的的方式来区分。


使用可搜索的名称

单字母名称和数字常量有个问题,就是很难在大片文章中找出来。

      找MAX_PASSENGERSIZE_PER_ORDER(每个订单乘客的最大人数)很容易,但是你要在整个工程中搜索出有效的数字9就比较麻烦了。

长名称由于短名称,搜索到的名称胜于自造编码代写的名称。

      单字母名称仅用于短方法的本地变量中。名称的长短应与其作用于大小相呼应。若变量或常量可能在代码中多处使用,则应该赋予以便于搜索的名称。采用能表达意图的名称,貌似拉长了函数代码,但是想想看,WORK_DAYS_PER_WEEK 要比数字 5好定位的多,二我们的代码中也就只剩下了体会作者意图的代码。


不要添加没用的语境

编码太多,无需在自找麻烦。把类型和作用域编进名称里面,徒增代码量和了解代码的负担。

      应该把类和函数做的足够小,消除对成员前缀的需要。使用能够高亮现实的编辑环境(现在的IDE几乎都支持)。


        Passenger类用于定义乘客信息实体。第一个声明的类中所有的字段均添加了passenger前缀,难道它比第二类更好吗?


添加有意的语境

       很少有名称能自我说明--多数多不能!你需要有良好的命名类、函数或者名称空间来放置名称,给读者提供语境。如果没有这坐,给名称添加前缀就是终极大招了。设想你有名为 firstName、 lastName、street、 city、houseNumber、state、zipcode等的变量。当他们搁在一块的时候明显构成了一个地址。不过假设只是在某个地方中看见其中某个孤零零的变量呢?还会理所当然的认为是个地址吗?

这个时候这需要添加前缀 addrFirstName、addrLastName、addrCity等,以此提供语境。

其他

      类和对象名称应该是名词或名词短语,如Customer、Account以及AddressParser之类的,秘避免使用 Manage ,Data 或者Info类。

      方法名应该是动词或者动词短语,如 post、get、match、save、insert、deleteIterm。属性的访问、修改以及断言等方法应该根据值命名,并依照 JavaBean标准加上 get、set 、is等前缀。

     在重载构造方法的时候,使用描述了参数的静态工厂方法名。

      给每一个抽象概念选一个词,并且一以贯之。例如,使用fetch、retrieve、get给在多个类中的同种方法命名,都能表达同一种意思,但是你怎么能记住在哪一个类中使用的哪一种命名的方法呢?现在IDE通常会有调用对象的方法列别,但是方法列表上却没有相应的注释,如果你的方法签名能过明确告诉你这个方法是干什么,那么你真是太幸运了。不过,不幸的是绝大多数的老代码并不会这样做。函数名称应该是对无二的,遵循同一种规则,而且要保持一致,你这样会节省很多花时间。

      此外,避免同一术语表示不同概念,同一概念使用不同的词来表示,这样基本就造成了双关语了。MongoDB 的 save() 、insert()以及insertAll()方法就用这问题。

     使用解决方案领域的名称、使用源自所设问题领域的名称。

     言到意到、意到言到!

后记    

       取名字的难点在于需要良好的描述技巧和文化背景。这不仅是一种技术、商业、管理问题,更是一种教学问题。然而,这个领域内的绝大多人都没有做得更好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,119评论 9 118
  • 1、引言 数据库设计过程中表、字段等的命名规范也算是设计规范的一部分,不过设计规范更多的是为了确保数据库设计的合理...
    SnowflakeCloud阅读 40,877评论 0 48
  • 今天的写作任务是用300字写一个你熟悉的人,家人,朋友,亲人,他们是你值得用文字记录的人。 立刻想到了你,我的老公...
    爱琴海_阅读 395评论 0 0
  • 说起童话故事,不得不吐槽。我小的时候,听的尽是些暗黑的鬼故事,很少听到温馨的童话故事。这些鬼故事,都是村里人或邻村...
    我馬虺隤阅读 567评论 0 1