函数

短小

函数应该尽量短小,20行封顶最佳。对于if语句、else语句、while语句等,其中的代码块应该只有一行。该行大抵应该是一个函数调用语句。这样不但能保持函数短小,而且,块内调用的函数能够拥有较具说明性的名称。

只做一件事

如果函数只是做了该函数名下同一抽象层上的步骤,则函数还是只做了一件事(函数中的语句都要在同一抽象层级上)。编写函数毕竟是为了把大一些的概念(换言之,函数的名称)拆分为另一抽象层上的一系列步骤。要判断函数是否不止做了一件事,还有一个方法,就是看是否能再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。

无副作用

函数承诺只做一件事,但还是会做其他被藏起来的事。比如,它会对自己类中的变量做出未能预期的改动(例如:在校验密码的函数中初始化会话),会导致古怪的时序性耦合及顺序依赖。如果一定要时序性耦合,就应该在函数名称中说明。

每个函数一个抽象层级

我们想要让代码拥有自顶向下的阅读顺序。我们想要让每个函数后面都跟着位于下一抽象层级的函数,这样一来,在查看函数列表时,就能循抽象层级向下阅读了。我把这叫做向下规则。程序就像是一系列TO起头的段落,每一段都描述当前抽象层级,并引用位于下一抽象层级的后续TO起头段落。

switch 语句

Switch天生要做N件事,因此尽量避免使用。如果要使用,尽量确保每个switch都埋藏在较低的抽象层级,而且永远不重复。可以通过JAVA的继承和多态避免使用switch,如工厂方法,将原来放在一个类方法中的switch逻辑分散到多个类中。

使用描述性的名称

函数名称能较好地描述了函数做的事,别害怕长名称。命名方式要保持一致。

对于一元函数, 函数和参数应当形成一种非常良好的动词/名词对的命名形式。例如,write(name)。我们也可以把参数的名称编码成了函数名。例如,assertEqual 改成 assertExpectedEqualsActual(expected,actual)。

函数参数

最理想的参数数量是零(零参数函数),其次是一(单参数函数),再次是二(双参数函数),应尽量避免三(三参数函数),尽量把二元函数和三元函数转化为一元函数。参数会增加函数理解的难度,也会增加测试成本。

输出参数

函数输出参数难以理解,我们惯于认为信息通过参数输入函数,通过返回值从函数中输出,因此尽量避免使用输出参数。如果函数必须要修改某种状态,就修改所属对象的状态来实现输出。

—元函数的普遍形式

一元函数通常是处理该参数的函数。

也可能是操作该参数,将其转换为其他的对象,再输出之。

还有就是程序将函数看作是一个事件,使用该参数修改系统状态。

尽量避免编写不遵循这些形式的一元函数。

标识参数

标识参数指向函数传入布尔值来执行不同的逻辑。这样做,方法签名立 刻变得复杂起来,大声宣布本函数不止做一件事。如果标识为true将会这样做,标识为false 则会那样做。如果函数需要标志参数,应该将函数一分为二。

参数对象

如果函数看来需要两个、三个或三个以上参数,就说明其中一些参数应该封装为类了。从参数创建对象,不仅减少参数数量,还可以将相关参数聚合在一起。

分隔命令与询问

函数要么做什么事(命令),要么回答什么事(询问),但二者不可得兼。函数应该修改某对象的状态,或是返回该对象的有关信息。两样都干常会导致混乱。

异常处理

使用异常替代返回错误码

命令式函数返回错误码(通知该操作是否成功)轻微**违反了命令与询问分隔的规则**。它鼓励了在if语句判断中把命令当作表达式使用。

if(deletePage(page) == E_OK)

当客户端调用多个返回错误码的函数时,代码会有大量的if语句,这会导致深层次的嵌套结构,并且要求调用者立刻处理错误。如果使用异常替代返回错误码,错误处理代码就能从主路径代码中分离出来, 得到简化。

另外返回错误码通常暗示某处有个类或是枚举,定义了所有错误码。这样的类就是一块依赖磁铁,其他许多类都得导入和使用它。当Error枚举修改时,所有这些其他的类都需要重新编译和部署。使用异常替代错误码,新异常就可以从异常类派生出来,无需重新编译或重新部署。

抽离try/catch代码块

不要在一个函数中既有try的处理逻辑又有catch处理逻辑,即把错误处理与正常流程放在一起。最好把try代码块的主体部分抽离出来,另外形成函数。

函数应该只做一件事。错误处理就是一件事。因此,处理错误的函数不该做其他事。即try应该在函数开头,catch/finally代码块后面也不该有其他内容。

避免代码重复

代码重复会降低可读性,因为代码因此而臃肿,且当算法改变时需要修改多处地方。我们可以通过将重复的代码抽离成函数,或者放在基类或者AOP来消除重复。

 结构化编程

对于较大的函数、函数中的每个代码块都应该有一个入口、一个出口。遵循这些规则,意味着在每个函数中只该有一个return语句。

小结

好的函数不是一开始就能写出来的,而是经过反复修改不断打磨形成的。

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

推荐阅读更多精彩内容