// 上一篇:分枝/叶子(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. c++中类对象的内存对齐

    很多C++书籍中都介绍过,一个Class对象需要占用多大的内存空间.最权威的结论是: *非静态成员变量总合.(not static) *加上编译器为了CPU计算,作出的数据对齐处理.(c语言中面试中经 ...

  2. 如何搭建个人博客网站(Mac)

    一直以为自己记忆力很好,毕业之后才发现,之前需要看一遍就能记住的东西,现在看两三遍才能有印象.而搞技术的,如果不及时的记录下当时的情景,过后很容易就忘记.所以,再次萌生了搭博客.写文章的想法(之前用D ...

  3. spring-aop的简单实例注解版

    项目结构如图,基本的spring的配置就不在赘述 1.首先编写自定义的切面类 package org.wu.test; import org.aspectj.lang.annotation.After ...

  4. [Linux] Desktop Management

    xrandr --output Virtual1 --mode 1360x768 Extend Display Size

  5. java异常之后代码执行测试

    1.程序代码: public static void main(String[] args) { int[] a = {1,2,3}; for(int i=0;i<4;i++){ System. ...

  6. Oracle 11g的安装

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

  7. JavaWeb(八)JQuery

    jQuery 市场用得比较多两个框架: jQuery 比较适合做一些互联网 的应用(12306.com,蘑菇街,美丽说,聚美) extjs 比较适合做后台管理系统(电商(订单管理),银行,电信) 核心 ...

  8. java se之File类

    遍历某个目录路径下的所有文件并打印输出: package com.led.file; import java.io.File; public class File_List { public stat ...

  9. [2013-07-22]varnish-cache 安装配置及体验笔记

    varnish安装 ubuntu12安装参考 其他系统参考 如果选择了直接从源安装的方式的话,就不要自己去编译了,以免出现意外(悲剧的我,varnishlog 有点问题,之前先编译安装了,再从源安装, ...

  10. 项目管理svn

    https://nchc.dl.sourceforge.net/project/tortoisesvn/1.9.6/Application/TortoiseSVN-1.9.6.27867-x64-sv ...