代码编程:(五)函数规范
来源:互联网 发布:java的语句类型 编辑:程序博客网 时间:2024/06/02 04:57
关于函数,摘抄了他人的一些规则,加入了少许自己的理解。
1 函数一定要“短小”
函数第一个规则就是要短小。每一行尽量不要超过150字符;每个函数保持20行左右最佳,不要超过100行。
遇到if else while等分支/循环语句,尽量保持里面的代码块只有一行,这行代码应该是一个函数调用语句。
2 函数保持“只做一件事”
函数应该做一件事,只做一件事,做好这件事。
一个函数所实现的功能越多,牵扯的功能越多,越容易让人难以阅读和理解。
如果一个函数实在要同时完成多个工作,那么多个工作应该再用其他函数实现,在该函数内部实现多个函数同一个层级的调用。这样可以保持函数的短小,还可以通过函数名快速理解大抵处理的内容。
3 每个函数一个抽象层级
想要确保函数只做一件事情,那么函数中的语句都要在同一抽象层级上。通过其他函数调用,使函数不要嵌套太多,嵌套越多,层级越多,理解起来越复杂。
如果让层级减少,就需要提供更多函数切分层级;这些函数最好遵循“向下规则”.
要让代码拥有自顶而下的阅读顺序。让每个函数后面都跟着位于下一抽象层级的函数,这样就便于查看函数时候,遵循抽象层级,自上而下阅读了。
4 switch语句
这个有点斤斤计较了,不过应该有一定道理。
传送门:switch语句
5 使用描述性的名称
比如获取蔬菜信息的方法用vegetablesInfosFromServer名称比getData要好很多。这样别人通过函数名,就明白函数要做什么事情。要遵循 沃德原则:“如果每个例程都让你感到深合己意,那就是整洁的代码”。
所以,起名字不要冗杂,但也别怕长。英语不好的小伙伴,还是要多提升英语能力,做到命名准确,言简意赅。
6 函数参数
最理想零参数;其次一个参数;再次两个参数;避免三个参数。除非有足够的理由,才使用三个以上的参数。
在OC编程过程中,一点要在参数前面的方法中,描述参数的含义。OC不同于其他语言,每个参数都可以单独在方法中对应描述。
7 无副作用
副作用是一种谎言。函数承诺只做一件事,但还是会做其他被藏起来的事。有时,它会对自己类中的变量做出未能预期的改动。有时,它会把变量搞成向函数传递的参数或是系统全局变量。无论哪种情况,都是具有破坏性的,会导致古怪的时序性耦合及顺序依赖。
传送门:无副作用
8 分割指令与询问
函数要么做什么事,要么回答什么事,但是两者不可兼得。函数应该修改某对象的状态,或者返回该对象的有关信息。两个都干常常会导致混乱。
传送门:分割指令与询问
9 使用异常替代返回错误码
这个单独拉出来。
从指令式函数返回错误码轻微违反了指令与询问分隔的规则。它鼓励了在if语句判断中把指令当作表达式使用。
- if (deletePage(page) == E_OK)
这不会引起动词/形容词混淆,但却导致更深层次的嵌套结构。当返回错误码时,就是在要求调用者立刻处理错误。
- if (deletePage(page) == E_OK) {
- if (registry.deleteReference(page.name) == E_OK) {
- if (configKeys.deleteKey(page.name.makeKey()) == E_OK){
- logger.log("page deleted");
- } else {
- logger.log("configKey not deleted");
- }
- } else {
- logger.log("deleteReference from registry failed");
- }
- } else {
- logger.log("delete failed");
- return E_ERROR;
- }
另一方面,如果使用异常替代返回错误码,错误处理代码就能从主路径代码中分离出来,得到简化:
- try {
- deletePage(page);
- registry.deleteReference(page.name);
- configKeys.deleteKey(page.name.makeKey());
- }
- catch (Exception e) {
- logger.log(e.getMessage());
- }
抽离try catch块:
Try/catch代码块丑陋不堪。它们搞乱了代码结构,把错误处理与正常流程混为一谈。最好把try和catch代码块的主体部分抽离出来,另外形成函数。
- public void delete(Page page) {
- try {
- deletePageAndAllReferences(page);
- }
- catch (Exception e) {
- logError(e);
- }
- }
- private void deletePageAndAllReferences(Page page) throws Exception {
- deletePage(page);
- registry.deleteReference(page.name);
- configKeys.deleteKey(page.name.makeKey());
- }
- private void logError(Exception e) {
- logger.log(e.getMessage());
- }
在上例中,delete函数只与错误处理有关。很容易理解然后就忽略掉。deletePageAndAllReference函数只与完全删除一个page有关。错误处理可以忽略掉。有了这样美妙的区隔,代码就更易于理解和修改了。
错误处理就是一件事
函数应该只做一件事。错误处理就是一件事。因此,处理错误的函数不该做其他事。这意味着(如上例所示)如果关键字try在某个函数中存在,它就该是这个函数的第一个单词,而且在catch/finally代码块后面也不该有其他内容。
错误依赖磁铁
返回错误码通常暗示某处有个类或是枚举,定义了所有错误码。
- public enum Error {
- OK,
- INVALID,
- NO_SUCH,
- LOCKED,
- OUT_OF_RESOURCES,
- WAITING_FOR_EVENT;
- }
这样的类就是一块依赖磁铁(dependency magnet);其他许多类都得导入和使用它。当Error枚举修改时,所有这些其他的类都需要重新编译和部署。 这对Error类造成了负面压力。程序员不愿增加新的错误代码,因为这样他们就得重新构建和部署所有东西。于是他们就复用旧的错误码,而不添加新的。
使用异常替代错误码,新异常就可以从异常类派生出来,无需重新编译或重新部署。
10 别重复做一件事
一段相同的代码在不同地方多次重复出现是很可怕的,会让代码显得臃肿,同时修改和维护也会造成很多负担。
11 结构化编程
适当的使用break,continue,return语句。准确表达自己的函数逻辑。
阅读全文
0 0
- 代码编程:(五)函数规范
- Java开发代码规范之编程规约(五)——集合处理
- c++编程规范学习笔记(五)
- C++编程(四)--- 代码规范
- 【编程素养】之代码规范(零)
- Delphi编程代码规范
- JAVA代码编程规范
- java编程代码规范
- android 编程代码规范
- IOS 编程 代码规范
- java编程代码规范
- Delphi编程代码规范
- Java代码规范编程
- Java代码规范编程
- iOS代码编程规范
- IOS 编程 代码规范
- 编程代码规范
- java代码编程规范
- Linux实时技术与典型实现分析-第 2 部分
- UVA 210 并行程序模拟
- Maven Build时提示:Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
- 使用IntelliJ IDEA导入storm-starter并测试WordCountTopology运行出现 A JNI error has occurred的原因和解决
- POJ 1083 Moving Tables
- 代码编程:(五)函数规范
- Linux 实时技术与典型实现分析, 第 1 部分: 介绍
- 读鸟哥linux私房菜有感(20170709)
- 深入理解linux网络技术内幕第一笔
- <Triggers><asp:PostBackTrigger ControlID="btnExportServiceAgency" /></Triggers
- 排序
- linux下杀死进程(kill)的N种方法
- LeetCode 70. Climbing Stairs
- Django-模版