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

// 下一篇:必经之地(using)


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

前情回顾

上一次,我们说到状态机结构(state machine),事实上,编程语言中有很多所谓的“高级”控制结构,内部都是状态机结构,差别只在于,这是编程语言内置提供的还是外置类库做。后面我们会有机会一点点展开它们,状态机的原理简洁,理解了它,再去理解那些高级控制结构的时候,才会觉的自然。再次回顾下状态机的原理:

  • define states
  • function dowork by switch states
  • in branch methods or events
    • check state
    • do real work
    • change state
    • reentry dowork function

下面我们看一种新的case。

典型代码

try-catch 情景

function loadPackage(packageName){
try{
let packageInfo = getPackageInfo(packageName);
let configPath = packageInfo.path + '/config.json';
let package = JSON.parse(fs.readFileSync(configPath));
return package;
}catch(err){
return null;
}
}

lock 情景

typedef std::map<K*,V*> Dict;
Dict dict;
Lock* lock = new Lock(); int Add(K* key, V* value){
lock->lock();
Dict::iterator it = dict.find(key);
if (it == Dict.end()){
key->AddRef();
value->AddRef();
dict.insert(std::make_pair(key, value));
}
lock->unlock();
return RESULT.SUCCESS;
} int Remove(K* key){
lock->lock();
K* oldKey = NULL;
V* oldValue = NULL; Dict::iterator it = dict.find(key);
if (it != dict.end()){
oldKey = it->first;
oldValue = it->second;
dict.erase(it);
} if (oldKey){
oldKey->Release();
} if (oldValue){
oldValue->Release();
} lock->unlock(); return RESULT.SUCCESS;
} V* Find(K * key){
lock->lock(); K* oldKey = NULL;
V* oldValue = NULL; dict::iterator it = dict.find(key);
if (it != dict.end())
{
oldKey = it->first;
oldValue = it->second;
} oldValue->AddRef(); lock->unlock();
return oldValue;
}

结构分析

上述两个示例代码,一个用到了try-catch,另一个用到了lock。例子里的代码不复杂,但是在编程中,也是一种常见的问题。那就是try-catch和lock的作用域是在一整段函数范围内都起作用。我们先缩小下范围:

try-catch 情景

function loadPackage(packageName){
let packageInfo = getPackageInfo(packageName);
let configPath = packageInfo.path + '/config.json'; // catch scope
try{
let package = JSON.parse(fs.readFileSync(configPath));
return package;
}catch(err){
return null;
}
}

lock 情景

typedef std::map<K*,V*> Dict;
Dict dict;
Lock* lock = new Lock(); int Add(K* key, V* value){
lock->lock();
Dict::iterator it = dict.find(key);
if (it == Dict.end()){
key->AddRef();
value->AddRef();
dict.insert(std::make_pair(key, value));
}
lock->unlock();
return RESULT.SUCCESS;
} int Remove(K* key){
K* oldKey = NULL;
V* oldValue = NULL; // lock scope
{
lock->lock();
Dict::iterator it = dict.find(key);
if (it != dict.end()){
oldKey = it->first;
oldValue = it->second;
dict.erase(it);
}
lock->unlock();
} if (oldKey){
oldKey->Release();
} if (oldValue){
oldValue->Release();
} return RESULT.SUCCESS;
} V* Find(K * key){
K* oldKey = NULL;
V* oldValue = NULL; // lock scope
{
lock->lock();
dict::iterator it = dict.find(key);
if (it != dict.end())
{
oldKey = it->first;
oldValue = it->second;
}
lock->unlock();
} oldValue->AddRef(); return oldValue;
}

语义分析

在上述两种情景下,关键是要区分出:“一个保护范围的作用目标是什么”。

try-catch只需要捕获文件读写和Json转换的异常,而不应该把其他代码包含进来。特别是getPackageInfo是一个函数调用,一个函数调用里面什么都可能发生,不应该被语义不明确地包含在此处的异常捕获里。

lock则要明确保护的是数据还是行为。此处lock应该保护的是dict容器在多线程里读写的互斥,所以不应该把除了对dict操作的其他逻辑包含进去。特别是oldKey->Release(), oldValue->Release()两个函数调用会有释放资源的行为,里面什么都可能发生,不应该被语义不正确地包含在此处的加锁范围内。

控制结构(4) 局部化(localization)的更多相关文章

  1. 控制结构(4): 局部化(localization)

    // 上一篇:状态机(state machine) // 下一篇:必经之地(using) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一次,我们说到状态机结构( ...

  2. feilong's blog | 目录

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

  3. 控制结构(5) 必经之地(using)

    // 上一篇:局部化(localization) // 下一篇:最近最少使用(LRU) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一周,我们谈到了分支/卫语句 ...

  4. 控制结构(3) 状态机(state machine)

    // 上一篇:卫语句(guard clause) // 下一篇:局部化(localization) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上次分析了guar ...

  5. 控制结构(3): 状态机(state machine)

    // 上一篇:卫语句(guard clause) // 下一篇:局部化(localization) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上次分析了guar ...

  6. 控制结构(5): 必经之地(using)

    // 上一篇:局部化(localization) // 下一篇:最近最少使用(LRU) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一周,我们谈到了分支/卫语句 ...

  7. PHP语法(三):控制结构(For循环/If/Switch/While)

    相关链接: PHP语法(一):基础和变量 PHP语法(二):数据类型.运算符和函数 PHP语法(三):控制结构(For循环/If/Switch/While) 本文我来总结几个PHP常用的控制结构,先来 ...

  8. Python 30分钟入门——数据类型 and 控制结构

    Python是一门脚本语言,我也久闻大名,但正真系统的接触学习是在去年(2013)年底到今年(2014)年初的时候.不得不说的是Python的官方文档相当齐全,如果你是在Windows上学习Pytho ...

  9. 学习scala03 控制结构

    scala拥有非常宽松的控制结构. if与while scala中的if和while几乎和java中的结构一模一样. //if语句 val a= ){ println(“”) }else{ print ...

随机推荐

  1. javaweb中的关于编码问题总结

    1.pageEncoding="utf-8" 设置JSP编译成Servlet时使用的编码 2.Contenttype="text/html;charset=utf-8&q ...

  2. Python获取秒级时间戳与毫秒级时间戳

    获取秒级时间戳与毫秒级时间戳 import time import datetime t = time.time() print (t) #原始时间数据 print (int(t)) #秒级时间戳 p ...

  3. 设计一个程序能够将某一个目录下面的所有文件名打印出来---File类的使用

    ,设计一个程序能够将某一个目录下面的所有文件名打印出来 运用到的方法有:返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录:list()           测试此抽象路径名表示的 ...

  4. 斜率DP hdu 3507

    Problem Description Zero has an old printer that doesn't work well sometimes. As it is antique, he s ...

  5. 16汇编第十讲完结Call变为函数以及指令的最后讲解

    16汇编完结Call变为函数以及指令的最后讲解 学了10天的16位汇编,这一讲就结束了,这里总结一下昨天的LOOP指令的缺陷,因为lOOP指令的缺陷,所以我们都改为下面的汇编代码使用了,自己去写,其中 ...

  6. 从送外卖到建站售主机还有共享自行车说起-2017年8月江西IDC排行榜与发展报告

    曾几何时,送外卖,这样的"低技术含量"工作,很难被互联网公司看上,直到百度将其当作连接终端用户与大数据的管道. 同样,销售主机域名和建站业务,本也是"微小体量" ...

  7. 解决在linux环境下面不显示验证码的问题

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt235 解决在linux环境下面不显示验证码的问题1.tomcat      ...

  8. CPU和GPU的差别

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt317 首先需要解释CPU和GPU这两个缩写分别代表什么.CPU即中央处理器, ...

  9. Unity3D安装破解教程(以Unity5.3.4为例)(转)

      Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎.目 ...

  10. 网络编程:基于C语言的简易代理服务器实现(proxylab)

    本文记录了一个基于c socket的简易代理服务器的实现.(CS:APP lab 10 proxy lab) 本代理服务器支持keep-alive连接,将访问记录保存在log文件. Github: h ...