如何编写可读性好的代码


1.什么样的代码是可读性好的代码?

“让人阅读你的代码,就像阅读文章一样流畅,就像阅读散文诗一样优美!”——这就是好代码!

把代码当作一篇优美的散文诗来写!用这样的标准来要求自己,一定会写出好代码,一定会成为一个优秀的程序员。

代码不仅是写给机器编译的,更是写给人看的!

代码不仅是代码,更是文档!

2.理清思路再动手——先写注释,再写代码

清晰的思路是编程行动的良好指南。花点时间思考一下,不要一接到任务就动手编代码,从而陷入技术细节不可自拔。

2.1 我的编程步骤

(1)在一个空的函数体内用注释写出自己的思路,如:

  //功能说明:XXX

  private void MyMainFunction()

  {

    //第1步,XXX

    //第2步,XXX

    MySubFunction ();//实现XXX

    //第3步,XXX

  }

  //功能说明:XXX

  private void MySubFunction()

  {

    //先空着

    return 0;

  }

(2)理清思路后,在空白处填写自己的代码。

如果某个步骤中实现起来感觉有点麻烦,那就先放一个空的子函数,为这个子函数建一个空的函数体——保证编译始终通过,稍后再填充这个空函数体。这种方法不影响你的整体思路,避免陷入编程细节,同时又让“大事化小,小事化了”。

(3)编完主函数后,填充空的子函数体。

其实是对(1)(2)的迭代。通过主函数的运行效果,可以实时检测子函数编写的正确与否。我们编写的子函数都即时被应用场景所调用,也就是即时的被测试,这不也是测试驱动的思想吗?事实证明,这样得到的函数,比预先设计的函数更有用。

这样,只要思路清晰正确,编程就不会走太大弯路。

2.2 注释应先于代码存在

注释应先于代码存在,而不是编写完代码之后去补注释。因为人固有的懒惰,编写完代码之后都不情愿再去主动加注释,这使得代码的可读性变差。

另外,利用空白或空白行合理分隔代码,也是一种良好的注释。就像好的文章印刷,段落间距要大一点是一样的。文章中也要留白!

C#代码中可使用region合理分隔代码,同时在region中加入注释。特别是,一定要把私有函数聚集到region中折叠起来,不要与公有函数(或事件函数)交叉,因为我们阅读代码往往是从公有函数(或事件函数)入手的。这可以隐藏细节,使代码看起来更整洁。

3.给变量起个好名字!

合理的变量命名是代码可读的基础。好的命名,不仅仅是使得代码易读,它代表了你对业务领域的理解,对程序逻辑的认知,对项目框架的把握。所以,好的程序员很多时候纠结的不是技术实现问题,而是如何为变量起一个好名字,使得代码读起来流畅,能让更多的人理解!

遵循一些成熟的命名规范,给变量起个好名字的事会容易一些。接下来,我们探讨一下常见的命名规范问题。

(1)常见的大小写命名法

PascalCasing(大写开头):用于名字空间、类型、成员等的命名,举例:FileStream。

camelCasing(驼峰命名法,小写开头):用于形参、局部变量、私有字段等的命名。举例EncryptFile(string plainFile, string cypherFile)。

匈牙利命名法(小写开头,首单词为数据类型):不推荐使用,因为IDE的智能提示很容易让你知道变量的类型。举例:intCount、iCount。(其实,我们对匈牙利命名法有误解,下篇再谈)

另外,微软建议不要在单词间使用下划线。

(2)名字空间的命名

Company.Product.Subnamespace。举例:

HuazemingTech.RailwayMis.Web

(3)类(结构)及对象的命名

名词或名词短语,因为它们代表系统中的实体。举例:

Student student;

List students;

(4)接口的命名

表示类型层次的根基时:名词或名词短语,如:IList;

表示某种能力时:形容词或形容词短语,如IComparable。

(5)方法的命名

动词或动词短语,DoSomething()。如:String.Split()

返回布尔值时使用表示肯定性的短语,并考虑第三人称。如:collection.Contains(item)

(6)属性的命名

名词短语或形容词。举例:

public class ListView{

public ItemCollection Items {get;}//这里用复数形式

}

用肯定性短语命名布尔属性,考虑前缀“Is/Can/Has”。举例:CanRead、IsPostBack。

(7)命名规范不是一成不变的

命名规范不是一成不变的,在特定场景下可以有自己风格的约定,前提是要使代码保持一致、易读。比如,一般我们强烈反对使用汉语拼音命名变量,可是在有些项目中,特别是涉及国内政府、院校的信息标准时,其数据库字段(量很大)完全是按汉语拼音首字母制定的,如果非要翻译成英文就有点矫枉过正了(工作量本身也很大)。一旦熟悉了这个行业之后,这些汉语拼音简写也就成了业务领域知识的一部分了,也就不那么别扭了,这也算中国特色吧。

4.如何检测你的代码是否规范?

(1)人工检测:让同伴阅读你的代码(结对编程,代码复审),发现问题。自我检测,不懈追求――“让人阅读你的代码,就像阅读文章一样流畅!”。

(2)工具检测:FxCop,微软的一个开发工具,可以对编译过的托管代码进行分析,并告诉用户哪些地方不符合设计规范。(博友【金色海洋(jyk)阳光男孩】推荐:R#--ReSharper: http://www.jetbrains.com/resharper/).

5.重构你的代码,做得更好一点点!

嗅嗅代码的坏味道:如果你发现在单页中写了过多的MySubFunction,如果你检测到不符合设计规范的代码,如果你写了过长的函数,如果你发现你在重复拷贝相同的代码段……是时候重构你的代码了!

何谓重构?重构是对软件内部结构的一种调整,目的是在不改变软件可察行为的前提下,提高其可理解性,降低其修改成本。

为何重构?改进软件设计(消除重复,Don’t Repeat Yourself);使代码更易理解(提高可读性);帮你找到Bug(Keep Your Code Clean);助你提高编程速度(后退是为了大踏步的前进)。

何时重构?三次法则:事不过三,三则重构。重构不是重构的目的,当重构能帮助你把后续的事情做得更好,那么还等什么?重构的时机:添加功能时,修补错误时,复审代码时。

如何重构?小步前进,不断验证。(Done is Better Than Perfect)

常见的重构原因和对策:

(1)代码重复。提取为公共类/函数。

(2)代码形式重复。考虑模板类/泛型。

(3)过多函数的类。考虑使用partial分部类,将类分拆到多个文件中去,每个分部类对应一个文件。如MVC中Controller类往往会成为包含过多Action函数的类,就可将其按功能域拆分为多个分部类。

(4)过长的参数列表。构造一个对象,包含所有要用的参数,然后将这个对象当作参数即可。

编程的过程实际是一个不断重构(改进)的过程。通过不断重构,可以去除代码的坏味道,编写可读性更好的代码。同时也深化了你对设计的理解,提高了你的编程素养。

重构,是一种生活态度,每天做得更好一点点。不要有过多的期望,一点点就好!不断前进,逐步逼近完美。

6.向微软学习,向MSDN学习!

微软作为业界最为成功的软件生产商,在各方面都有值得我们学习的地方。我觉得Windows、Office等是我们做界面和为用户设计操作模式的最好老师,当我没有思路的时候,我都会打开Windows的某个功能看看,就会受到启发。

MSDN是我们学习编程的最好老师。MSDN是众多大师的智慧结晶。经常看MSDN中的类库,不仅可以系统的掌握类库的功能,还可以学到如何给变量命名,如何进行架构设计等。看MSDN中的示例代码,也是快速上手的捷径;特别是一些“快速指南”,能很快让你了解某个方面的开发技术。总之,看MSDN有百利而无一害,呵呵,比看很多烂书强多了。(最近也发现了MSDN中一些代码比较烂)

MSDN是帮助文档,我们在使用很多软件遇到问题时,是否忽略了开发者精心给我们准备的帮助文档呢?

(现在做APP,没思路的时候就看看淘宝、京东、微信、支付宝,看他们的UI布局/设计、看他们的操作流程,能够得到启发)

7.小结

通过注释理清思路,给变量起好名字,重构你的代码,从MSDN中领悟大师真谛,其实都是一些编程习惯,养成好的、适合自己的习惯会受益终身。软件大师Kent Beck说:

“我不是个伟大的程序员,我只是个有着一些优秀习惯的程序员而已。”

——与诸君共勉!希望大家都成为具有优秀习惯的程序员,编写散文诗一样的代码!

参考文献/推荐阅读:

《编写可读代码的艺术》

《代码整洁之道》

《.NET设计规范:约定、惯用法与模式》

《重构——改善既有代码的设计》

备注:本文以C#编程为例,不足之处,敬请批评指正。这是本人以前写的文章,第一次使用“简书”,试发一下,欢迎交流。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,563评论 25 707
  • 从百度文库下载下来的,这里保存一份 别人的原代码程序员怎样阅读 源码就是指编写的最原始程序的代码。 运行的软件是要...
    Albert陈凯阅读 3,323评论 0 15
  • 累并快乐的一天!今天有两件重要事,一是我们一年级二班执勤,主要在放学的时间拦截车辆禁止进入!二是小朋友们下午为迎十...
    Kitty粉樂樂阅读 204评论 0 0
  • 唱一首歌 熟悉大段歌词 却忘记了名字 念一个人 记得好多细枝末节 却只属于回忆 你轻轻唱着的时候,可能某个人在听 ...
    一窗秋阳阅读 82评论 0 0