// 上一篇:分枝/叶子(branch/leaf)

// 下一篇:状态机(state machine)


基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构。

典型代码:

  • 同步版本
function loadFunc(funcInfo){
if(funcInfo){
let funcObj = doParserFunc(funcInfo);
if(funcObj){
let package = doLoadPackage(funcObj.packageName);
if(pacakge){
let module = doLoadModule(pacakge,funcObj.moduleName);
if(module){
let func = module[funcObj.functionName];
if(func){
return func;
}else{
// do something
}
}else{
// do something
}
}else{
// do something
}
} else {
// do something
}
}
return null;
}
  • 异步版本
function loadFunc(funcInfo, onComplete){
if(funcInfo){
let funObj = doParseFunc(funcInfo);
if(funcObj){
doLoadPackage(funcObj.packageName, function(err,package){
if(package){
doLoadModule(package, funcObj.moduleName, function(err, module){
if(module){
let func = module[funcObj.functionName];
if(func){
onComplete(0,func);
}else{
onComplete(1);
}
}else{
onComplete(1);
}
})
}else{
onComplete(1);
}
});
}else{
onComplete(1);
}
}else{
onComplete(1);
}
}

结构分析

无论是同步版本,还是异步版本,都存在嵌套持续变深的问题。随着开发的进行,需求的变更,代码会变的越发繁杂。一种方式是通过上一节的方式,合理组织函数的分层,让函数的组织表达更清晰。但是另一方面,在支持lambda表达式和匿名函数的语言里,编程的时候总是会大量使用语言提供的这种便利,写带有许多lambda表达式或匿名函数的逻辑代码。一种常见的方式是使用卫语句(guard clause)的方式提前返回,减少嵌套。

  • 同步版本
function loadFunc(funcInfo){
if(!funcInfo){
return null;
} let funcObj = doParserFunc(funcInfo);
if(!funcObj){
return null;
} let package = doLoadPackage(funcObj.packageName);
if(!package){
return null;
} let module = doLoadModule(pacakge,funcObj.moduleName);
if(!module){
return null;
} let func = module[funcObj.functionName];
if(!func){
return null;
} return func;
}
  • 异步版本
function loadFunc(funcInfo, onComplete){
if(!funcInfo){
return onComplete(RESULT.INVALID_PARAMETER);
} let funcObj = doParserFunc(funcInfo);
if(!funcObj){
return onComplete(RESULT.PARSE_ERROR);
} doLoadPackage(funcObj.packageName, function(err,package){
if(!package){
return onComplete(RESULT.LOAD_PACKAGE_FAILED);
} doLoadModule(package, funcObj.moduleName, function(err, module){
if(!module){
return onComplete(RESULT.LOAD_MODULE_FAILED);
} let func = module[funcObj.functionName];
if(!func){
return onComplete(RESULT.FUNC_NOT_EXIST);
} onComplete(RESULT.SUCCESS,func);
});
});
}

语义分析

编程语言提供的if/else结构,有两种基本的用法:

  • 优先考虑满足条件就做什么
if(condition){
doSomething();
}else{
logError();
}
  • 优先考虑不满足条件就处理错误
if(!condition){
logError();
}else{
doSomething();
}

这两种结构,各自都能写出逻辑严密的代码。例如,在前一种优先模式下,一种重要的方式把所有的if分支都写下它的else分支,保证逻辑上少漏洞。典型的控制结构是这样的:

if(condition1){
// <a>
if(condition2){
// <b>
if(condition3){
// <c>
if(condition4){
// <d>
doSomething1();
}else{
// <e>
doSomething2();
}
}else{
// <f>
doSomething3();
}
}else{
// <g>
doSomething4();
}
}else{
// <h>
doSomething5();
}

这种结构确实也能更直接的和大脑里的流程结构对上,如果勤快一点画流程图,也能直接对上。程序是会根据需求变化的,在需求变化的时候,很容易在上述<a><b>, ...处产生碎片代码,此时如果对上一节介绍的函数分层有比较好的实施,则代码依然保持良好的可读/可维护。

但是,在混合了同步、异步之后,即使有了良好的函数组织,也还是容易出现嵌套深的情况,此时,可以配合适当的guard结构去组织代码。使用guard语句,可以让代码更加线性化。具体在情景代码中应该使用哪种方式,就是一种编程中的选择问题。如果考虑一致性,最好一个模块保持一致。

控制结构(2) 卫语句(guard clause)的更多相关文章

  1. 控制结构(2): 卫语句(guard clause)

    // 上一篇:分枝/叶子(branch/leaf) // 下一篇:状态机(state machine) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 典型代码: 同步版本 f ...

  2. Replace Nested Conditional with Guard Clauses(用卫语句代替嵌套循环)

    函数中的条件逻辑,使人难以看清正常的执行路径. 使用卫语句表现所有特殊情况. double getPayAmount() {double result;if (_isDead) result = de ...

  3. java - 策略模式、状态模式、卫语句,避免多重if-else(转)

    前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...

  4. Java重构-策略模式、状态模式、卫语句

    前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...

  5. 【转】Java重构-策略模式、状态模式、卫语句

    前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...

  6. Swift基础之守卫语句guard

    本篇文章翻译自:http://ericcerney.com/swift-guard-statement/原作者:ecerney该语法为swift2.0之后添加的新特性 最开始在Apple的Platfo ...

  7. feilong's blog | 目录

    每次把新博客的链接分享到技术群里,我常常会附带一句:蚂蚁搬家.事实上也确实如此,坚持1篇1篇的把自己做过.思考过.阅读过.使用过的技术和教育相关的知识.方法.随笔.索引记录下来,并持续去改进它们,希望 ...

  8. Effective Scala

    Effective Scala Marius Eriksen, Twitter Inc.marius@twitter.com (@marius)[translated by hongjiang(@ho ...

  9. ruby编程语言-学习笔记5(第5章 语句和控制结构)

    以下是2种表达方式一样. if expression code end if expression then #推荐这种形式 code end expression的值不是false或nil,则cod ...

随机推荐

  1. # webpack 3 & React 的简单配置 。

    今天真是难过的一天

  2. .Net Core下使用WCF

    在.net core 下的wcf 和framework下的wcf使用方式有点不太一样.在core下用wc,需要安装VS扩展Visual Studio WCF Connected Service,目前这 ...

  3. Lightoj1205——Palindromic Numbers(数位dp+回文数)

    A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the sam ...

  4. ReactiveCocoa源码解读(二)

    上一篇解读了ReactiveCocoa的三个重要的类的底层实现,本篇继续. 一.RACMulticastConnection 1.应用 RACMulticastConnection: 用于当一个信号被 ...

  5. 腾讯织云:DevOps 流水线应用平台践行之路

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:梁定安,腾讯织云负责人,目前就职于腾讯社交网络运营部,任运维技术总监,开放运维联盟委员,腾讯云布道师,腾讯课堂运维讲师,EXIN D ...

  6. 【Linux】系统版本信息

    查看操作系统版本信息 dream361@master:~$ cat /etc/issue Ubuntu 16.04.2 LTS \n \l dream361@master:~$ lsb_release ...

  7. ThinkPHP系统变量,常量,序列化,反序列化,缓存

    变量的输出: 在模板中输出一个变量有两种形式:{$list.name} {$list[‘name’]} 在模板中可以使用系统变量,以$Think.开头 系统变量:(举例选几个) 获得服务器的IP地址: ...

  8. Oracle 11g的安装

    选择对应版本的Oracle 11g: 解压之后,点击"setup.exe"进行安装. 如果希望接受Oracle的广告邮件可以留下自己的电子邮件地址, 如果希望通过My Oracle ...

  9. Visual Studio Code 配置C++环境

    Visual Studio Code (简称 VS Code / VSC) 是一款免费开源的现代化轻量级代码编辑器,支持几乎所有主流的开发语言的语法高亮.智能代码补全.自定义热键.括号匹配.代码片段. ...

  10. 进程管理之system

    system定义 #include<stdlib.h> int system(const char *command); 首先要知道,system函数是c库中的函数,而不是系统调用.其实s ...