控制结构(4): 局部化(localization)
// 上一篇:状态机(state machine)
// 下一篇:必经之地(using)
基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构。
前情回顾
上一次,我们说到状态机结构(state machine),事实上,编程语言中有很多所谓的“高级”控制结构,内部都是状态机结构,差别只在于,这是编程语言内置提供的还是外置类库做。后面我们会有机会一点点展开它们,状态机的原理简洁,理解了它,再去理解那些高级控制结构的时候,才会觉的自然。再次回顾下状态机的原理:
- define states
- function
doworkby switch states - in branch methods or events
- check state
- do real work
- change state
- reentry
doworkfunction
下面我们看一种新的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)的更多相关文章
- 控制结构(4) 局部化(localization)
// 上一篇:状态机(state machine) // 下一篇:必经之地(using) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一次,我们说到状态机结构( ...
- feilong's blog | 目录
每次把新博客的链接分享到技术群里,我常常会附带一句:蚂蚁搬家.事实上也确实如此,坚持1篇1篇的把自己做过.思考过.阅读过.使用过的技术和教育相关的知识.方法.随笔.索引记录下来,并持续去改进它们,希望 ...
- 控制结构(5) 必经之地(using)
// 上一篇:局部化(localization) // 下一篇:最近最少使用(LRU) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一周,我们谈到了分支/卫语句 ...
- 控制结构(3) 状态机(state machine)
// 上一篇:卫语句(guard clause) // 下一篇:局部化(localization) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上次分析了guar ...
- 控制结构(3): 状态机(state machine)
// 上一篇:卫语句(guard clause) // 下一篇:局部化(localization) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上次分析了guar ...
- 控制结构(5): 必经之地(using)
// 上一篇:局部化(localization) // 下一篇:最近最少使用(LRU) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一周,我们谈到了分支/卫语句 ...
- PHP语法(三):控制结构(For循环/If/Switch/While)
相关链接: PHP语法(一):基础和变量 PHP语法(二):数据类型.运算符和函数 PHP语法(三):控制结构(For循环/If/Switch/While) 本文我来总结几个PHP常用的控制结构,先来 ...
- Python 30分钟入门——数据类型 and 控制结构
Python是一门脚本语言,我也久闻大名,但正真系统的接触学习是在去年(2013)年底到今年(2014)年初的时候.不得不说的是Python的官方文档相当齐全,如果你是在Windows上学习Pytho ...
- 学习scala03 控制结构
scala拥有非常宽松的控制结构. if与while scala中的if和while几乎和java中的结构一模一样. //if语句 val a= ){ println(“”) }else{ print ...
随机推荐
- static 静态与非静态的区别
静态属性是共享一块内存空间.实例的是各自独享一块内存空间. 比如同一个name属性.如果是实例成员.那么你每创建了一个对象.赋给name值.假如创建了2个对象.第一个赋值张三.第2个赋值李四.它们就分 ...
- WPF xaml中列表依赖属性的定义
列表内容属性 如上图,是一个列表标题排序控件,我们需要定义一个标题列表,从而让调用方可以自由的设置标题信息. 在自定义控件时,会遇到列表依赖属性,那么该如何定义呢? 下面是错误的定义方式: /// & ...
- C# 添加、修改以及删除Excel迷你图表的方法
Excel表格中的迷你图表能够直观地向我们展示出数据的变化趋势.本文将介绍C#如何实现为表格数据生成迷你图表,以及修改和删除迷你图表的方法.下面将详细讲述. 所用组件工具:Spire.XLS for ...
- linux部署二:网卡配置和Yum源的替换
一,初次登陆: 1.登陆(用root登陆)(1).账户名root(2).密码 ....2.工作界面切换A.Ctrl + alt + F1 : 图形化界面B.Ctrl + alt + F2----F6 ...
- 让priority_queue支持小根堆的几种方法
点击这里了解什么是priority_queue 前言 priority_queue默认是大根堆,也就是大的元素会放在前面 例如 #include<iostream> #include< ...
- [翻译] Oracle Database 12c 新特性Multitenant
译自官方白皮书http://www.oracle.com/technetwork/database/plug-into-cloud-wp-12c-1896100.pdf,包含新的云计算相关技术的介绍. ...
- 在AndroidStudio上使用AddressSanitizer
在AndroidStudio上使用AddressSanitizer AddressSanitizer是Google主导的一个开源内存问题检测工具.现在也开始支持Android平台,且受Google推荐 ...
- Android 运行报错 Unknown failure (at android.os.Binder.execTransact(Binder.java:681)) Error while Installing APKs 解决办法
今天,我用手机测试的时候出现了这个错误 我网站查找了一会资料, 在运行的时候出现提示大致意思:卸载删除已存在应用程序,是否卸载现有应用程序,点击ok就会出现如下错误 原应用程序也没有卸载,然后自己手动 ...
- 当我们按下电源键,Android 究竟做了些什么?
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由goo发表于云+社区专栏 相信我们对Android系统都不陌生,而Android系统博大精深,被各种各样的智能设备承载的同时,我们会否 ...
- "'cl' 不是内部或外部命令,也不是可运行的程序"解决方案
最近使用VS2012+Qt5.1+QtCreator2.8.1来搭建Qt的开发环境(之前有用MinGW编译的经历,经常碰到gdb调试器崩溃的问题),全部换成想用VC的编译器和调试环境,但是觉得QtCr ...