控制结构(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 ...
随机推荐
- Mysql中Count函数的正确使用
备注: 直接使用Count(*)或Count(1)这些大家基本都会,主要是Count函数还可以加满足表达式的统计:express 关于Count函数表达式的用法,目前个人只知道2种: a:使用:Cou ...
- MyCat做MySQL负载均衡(享学课堂,咕泡学院听课笔记)
不要用战术上的勤奋,掩盖战略上的懒惰. 一.数据库集群演示 演示的数据库的表分了三种, 1.配置表,存储一些配置文件,其他业务表需要关联读取,每个数据库都存储配置表的全部内容,即操作Mycat,所有集 ...
- java 线程方法 ---- yiled()
class MyThread3 implements Runnable{ @Override public void run() { for (int i = 0; i < 3; i++){ / ...
- ARM汇编指令集_学习笔记(1)
一.什么是ARM汇编? 运行在ARM处理器上的汇编语言就叫ARM汇编. C程序运行在X86平台,底层就是X86汇编:运行在ARM平台,底层就是ARM汇编.ARM汇编与X86汇编有显著区别. X86属于 ...
- Docker 创建 Confluence6.12.2 中文版
目录 目录 1.介绍 1.1.什么是Confluence? 2.Confluence的官网在哪里? 3.如何下载安装? 4.对 Confluence 进行配置 4.1.设置 Confluence 4. ...
- PJSUA2开发文档--第六章 媒体 Media类
6. 媒体(Media) 媒体对象是能够产生媒体或接受媒体的对象. Media的重要子类是AudioMedia,它代表音频媒体.PJSUA2支持多种类型的音频媒体对象: 捕获设备的AudioMedia ...
- 谈谈你对this对象的理解
理解: 1.this是js 的一个关键字,随着函数的使用场合的不同,this 的值会发生变化. 2.一个总原则:即this指的是调用函数的那个对象. 3.一般情况下,this 是全局对象,可以作为方法 ...
- 无法确定条件表达式的类型,因为“<null>”和“System.DateTime”之间没有隐式转换----解决办法
例子:(报错了) public DateTime? time { get; set; } time = item.HospOutDate.HasValue ? DateTime.Parse(item. ...
- C 存储类
存储类定义 C 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C 程序中可用的存储类: auto.register.static.extern auto ...
- python3字符串格式化format()函数的简单用法
format()函数 """ 测试 format()函数 """ def testFormat(): # format()函数中有几个元素, ...