// 上一篇:状态机(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. WPF 中图片的加载 ,使用统一资源标识符 (URI)

    在wpf中,设置图片路径有2种方法: 1.xaml文件中,指定路径 <Button Name=" HorizontalAlignment="Right" Verti ...

  2. VSTO中Word的查找方式

    VSTO中Word的查找方式 前言 使用C#在VSTO开发Word插件的过程,经常需要对文档中的内容进行查找和替换.在Word中进行文本的查找替换,和一般对纯文本的查找替换却不太一样.因为Word文档 ...

  3. [PHP] 按位与& 或| 异或^ 的日常使用

    按位与:0&0=0; 0&1=0; 1&0=0; 1&1=1;按位或:0|0=0: 0|1=1: 1|0=1: 1|1=1;按位异或,在或的基础上1 1也为0:0^0= ...

  4. Go中变量作用域的小坑

    直接上一实例: package main import "fmt" func main(){ fmt.Println("for start") ; a < ...

  5. C#/VB.NET 给Word文档添加/撤销书签

    在现代办公环境中,阅读或者编辑较长篇幅的Word文档时,想要在文档中某一处或者几处留下标记,方便日后查找.修改时,需要在相对应的文档位置插入书签.那对于开发者而言,在C#或者VB.NET语言环境中,如 ...

  6. Maven(九)Eclipse创建Web项目(简单方式)

    1. 创建Maven项目(以简单方式) 2. 勾选WAR 3. 选择properties->projectFacts 此处的错误可忽略,配置好会会消失,主要缺失web.xml文件 4. 将框中选 ...

  7. 实现PHP内部的通知机制,如当一个类的属性发生变化时,另外一个类就可以收到通知

    设计模式:观察者模式 当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新. 使用场景 一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新 ...

  8. LeetCode 176. 第二高的薪水(MySQL版)

    0.前言 最近刷LeetCode 刷数据库题目 由于数据库课上的是SQL,而MySQL有许多自己的函数的,怕把刚学会的函数忘记 特在此记录! 1.题目 编写一个 SQL 查询,获取 Employee ...

  9. js实现消息滚动效果

    <div class="inform" style=""> <div style="height:35px; overflow:hi ...

  10. Kasaraju算法--强连通图遍历及其python实现

    在理解有向图和强连通分量前必须理解与其对应的两个概念,连通图(无向图)和连通分量. 连通图的定义是:如果一个图中的任何一个节点可以到达其他节点,那么它就是连通的. 例如以下图形: 这是最简单的一个连通 ...