Cleaner, more elegant, and wrong(翻译)
Cleaner,more elegant,and wrong
整洁,更优雅,但是错的
并不是因为你看不到错误的产生路径就意味着它不存在。
下面是C#编程书中的一个片段,摘自关于异常处理的章节。
try {
AccessDatabase accessDb = new AccessDatabase();
accessDb.GenerateDatabase();
} catch (Exception e) {
// Inspect caught exception
}
public void GenerateDatabase()
{
CreatePhysicalDatabase();
CreateTables();
CreateIndexes();
}
Notice how much cleaner and more elegant [this] solution is.
请看这个解决方案是多么地整洁和优雅。
整洁,更优雅,但是错的。
假设在CreateIndexes()中抛出异常。GenerateDatabase()函数没有捕获它,所以错误被抛给执行catch的调用者,
当异常离开GenerateDatabase()时,重要信息已经丢失:数据库创建的状态捕获异常的代码不知道数据库创建的哪个步骤失败了。是否要删除索引?是否需要删除表吗?是否需要删除物理数据库?它不知道。
因此,如果创建CreateIndexes()时出现问题,则永远会泄露物理数据库文件和表。(由于这些可能是磁盘上的文件,所以它们无限期地挂起)。
在异常抛出模型中编写正确的代码比错误代码模型中更难,因为任何事情都可能是吧,您必须做好准备。在错误代码模型中,什么时候必须要检查错误是很明显的:当收到错误代码时。在异常处理模型中,你只需要错误可能会发生在任何地方。
换句话说,在错误代码模型中,很明显的是如当有人处理错误失败:他们没有检查错误代码。但是在一个异常抛出模型中,从代码中看不出是否有人处理错误,因为错误并不是明确的。
考虑如下:
Guy AddNewGuy(string name)
{
Guy guy = new Guy(name);
AddToLeague(guy);
guy.Team = ChooseRandomTeam();
return guy;
}
这个函数创建一个新的Guy,将他加入了联盟,并随机分配给一个团队。没有比这更简单的了。
记住:每一行都可能发生错误。
如果 “new Guy(name)“抛出异常怎么办?
好吧,幸运的是,我们还没有开始做任何事情,所以没有任何伤害 。
如果“AddToLeague(guy)“抛出异常怎么办?
我们创建的“Guy“将被放弃,GC将会清理它。
如果“guy.Team = ChooseRandomTeam()“抛出异常怎么办?
呃哦,现在我们很麻烦我们已经把这个人加入了联盟。如果有人捕获这个异常,他们将在联盟中找到一个不属于任何球队的人。如果有一些代码遍历联盟的所有成员,并使用gue.Team成员,他们将会获得NullReferenceException,因为guy.Team尚未初始化。
在编写代码时,您是否考虑到每行代码引发异常的后果呢?如果你打算写正确的代码,你必须这样做。
好吧,怎么解决这个问题?对操作重新排序。
Guy AddNewGuy(string name)
{
Guy guy = new Guy(name);
guy.Team = ChooseRandomTeam();
AddToLeague(guy);
return guy;
}
这种看似微不足道的变化对错误恢复有很大的影响。通过延迟提交数据(将guy加入到联盟),任何人员在创建过程中所遇到的异常都没有持久的影响。发生异常时,部分构造的guy被遗弃,最终被GC回收。
当然,这个例子很简单,因为设置guy的步骤没有副作用。如果设置过程中出现错误,我们可以抛弃guy,让GC清理回收。
在现实世界中,事情是比较麻烦的。考虑以下几点:
Guy AddNewGuy(string name)
{
Guy guy = new Guy(name);
guy.Team = ChooseRandomTeam();
guy.Team.Add(guy);
AddToLeague(guy);
return guy;
}
这与我们修正的函数一样,只是有人认为:如果每个球队保留一个成员列表,将会更有效率。所以您必须将自己添加到打算加入的球队中。这样做对函数的正确性有什么样后果?
Cleaner, more elegant, and wrong(翻译)的更多相关文章
- Cleaner, more elegant, and harder to recognize(翻译)
Cleaner, more elegant, and harder to recognize 更整洁,更优雅,但更难识别 看来,有些人把我几个月前一篇文章的标题"Cleaner,more e ...
- Cleaner, more elegant, and wrong(msdn blog)
Cleaner, more elegant, and wrong Just because you can't see the error path doesn't mean it doesn't e ...
- Cleaner, more elegant, and harder to recognize (msdn blog)
It appears that some people interpreted the title of one of my rants from many months ago, "Cle ...
- Go 开发关键技术指南 | 敢问路在何方?(内含超全知识大图)
作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 Go 开发关键技术指南文章目录: 为什么你要选择 Go? Go 面向失败编程 带着服务器编程金刚经走进 2020 年 敢问路在何方? Go 开发指南大图 ...
- Go 开发关键技术指南 | Go 面向失败编程 (内含超全知识大图)
作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 关注"阿里巴巴云原生"公众号,回复 Go 即可查看清晰知识大图! 导读:从问题本身出发,不局限于 Go 语言,探讨服务器中常常遇到的 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之四
七.创建和运行一个后台线程 Java中有一种特别的线程叫做 deamon(后台) 线程.这类线程具有非常低的权限,并且只有在同一个程序中没有其他的正常线程在运行时才会运行.注意:当一个程序中只剩下后台 ...
- [翻译]Java垃圾收集精粹(Java Garbage Collection Distilled)
source URL: http://www.infoq.com/articles/Java_Garbage_Collection_Distilled Name: Java Garbage Colle ...
- Effective Java 第三版——8. 避免使用Finalizer和Cleaner机制
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- PEP8中文翻译(转)
原文:https://github.com/zgia/manual PEP 8 -- Style Guide for Python Code PEP Index > PEP 8 -- Style ...
随机推荐
- JAVA的向上转型和向下转型怎么理解呢?
在定义中是子类向父类转型称为向上转型,父类向子类转型是向下转型(必须先向上转型过,才能向下转型), 但是在下面类定义后,我得到的结果却不同.求大佬解惑 class superclass{ public ...
- angular中复制文字到剪切板
function copyToClipboard(oElement, value) { var aux = document.createElement("input"); if ...
- HDU1284--完全背包
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 矩阵的奇异值分解(SVD)(理论)
矩阵的奇异值分解(Singular Value Decomposition,SVD)是数值计算中的精彩之处,在其它数学领域和机器学习领域得到了广泛的应用,如矩阵的广义逆,主分成分析(PCA),自然语言 ...
- 利用spring,实现package下的类扫描
项目中需要用到包扫描的情况是很多的,一般是在项目初始化的时候,根据一些条件来对某个package下的类进行特殊处理.现在想实现的功能是,在一个filter或interceptor初始化的时候,扫描指定 ...
- google软件测试之道读后感(二)
这几天又翻了几页这本书,觉得妙语连珠,关键语录摘抄如下,并补充自己的一些思考: "如果你想要求一个团队去尝试新的事物或者做某些改进,给他们提供一个联系人会更好一些,这个联系人来源于更大的社区 ...
- Nginx软件部署配置过程
---恢复内容开始--- 注意:博主使用的系统为: [root@web01 ~]# uname -a Linux web01 2.6.32-696.el6.x86_64 #1 SMP Tue Mar ...
- 机器学习笔记1 - Hello World In Machine Learning
前言 Alpha Go在16年以4:1的战绩打败了李世石,17年又以3:0的战绩战胜了中国围棋天才柯洁,这真是科技界振奋人心的进步.伴随着媒体的大量宣传,此事变成了妇孺皆知的大事件.大家又开始激烈的讨 ...
- Swift开发教程--使用Storyboard进行界面跳转
使用storyboard结合代码来做确实能够给开发带来非常多的便利. 在实践的过程中,我们常常会遇到界面的跳转问题. 通过控件和界面的建立的"连接"就能够了. 假设是navigat ...
- HDU 4960 Another OCD Patient(记忆化搜索)
HDU 4960 Another OCD Patient pid=4960" target="_blank" style="">题目链接 记忆化 ...