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 ...
随机推荐
- Python中的选择排序
选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大 ...
- JavaWeb框架_Struts2_(七)----->文件的上传和下载
这个章节是Struts2框架应用最广泛的三个版块(上传下载.国际化.校验输入)之一,所以这一版块的学习还蛮重要的. 1. 章节目录 Struts2文件上传 单文件上传 拦截器实现文件过滤 文件上传常量 ...
- Wannafly挑战赛3 record
B 遇见 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 65536K,其他语言131072K64bit IO Format: %lld题目描述A和B在同一条路上,他们之间的距离为 k ...
- HDU1248--完全背包
寒冰王座 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- svn搭建文档
1.制作本地yum源 a)挂载光盘 [root@localhost ~]# mount /dev/cdrom /mnt b)删除/etc/yum.repos.d目录所有的repo文件 [root@ ...
- javascript设计模式——模板方法模式
前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...
- beautifulSoup模块
这个库用来对网页进行解析功能,十分强大,有了它我们可以减少对正则的使用,也能顺利的从网页源码中拿到我们要的值.他是一个灵活,方便的网页解析库,处理高效,支持多种解析器. 这个库把HTML源码解析成对象 ...
- C#中级-从零打造基于Socket在线升级模块
一.前言 前段时间一直在折腾基于Socket的产品在线升级模块.之前我曾写过基于.Net Remoting的.基于WCF的在线升级功能,由于并发量较小及当时代码经验的不足一直没有实际应用. ...
- Cocos2d-X 精灵、动作效果
命名空间宏: USING_NS_CC; 感觉事实上挺鸡肋的. NS_CC_BEGIN. == using namespace cocos2d{ NS_CC_END ; } 推断一个精灵被点击: 1.层 ...
- NHibernate3剖析:Configuration篇之SessionFactory lambda配置
概览 在NHibernate3.0中.SessionFactory的Properties和Cache配置实现了流配置(fluent-configuration)和lambda表达式配置(lambda- ...