ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

软件构造-失败原子性

2022-06-24 01:01:59  阅读:160  来源: 互联网

标签:状态 对象 构造 原子 失败 之前 软件 异常


  在研读《Effective Java》时发现其中提出了“努力使失败保持原子性”的概念,笔者认为十分重要且有用,这里将其归纳整理后贴出,也作为读书笔记自用。

概念

  当对象抛出异常之后,通常我们期望这个对象保持在一种定义良好的可用状态之中,基石失败是发生在执行某个操作的过程中间。对于受检异常(CheckException,必须捕获的异常)而言,这尤为重要,因为调用者期望能从这种异常中恢复。一般而言,失败的方法调用应该使对象保持在被调用之前的状态。具有这种属性的方法被称为具有失败原子性。

实现方法

使用immutable对象

  如果在发生异常时可能会创建新的对象,但是永远不会改变原有的对象,对象仍保持在被调用之前的状态。

对mutable对象在执行操作之前检查参数

  类似软件构造课程上所说的checkrep()函数,检查可变对象的有效性(rep),在对象的状态被修改之前,先抛出适当的异常。

调整计算处理过程

  调整计算处理过程的顺序,使得任何可能会失败的计算部分都在对象被修改之前发生。例如对于一个Map对象,它的元素被按照某种特定的顺序做了排序,为了向其中添加元素,该元素的类型就必须是可以在该规则下与其他元素进行比较的。如果企图添加类型不正确的元素,在Map被修改之前,首先会导致某种异常。

在拷贝的对象上操作

  当需要对一个对象进行修改时,现在它的一份临时拷贝上执行操作,当操作完成后再用其中的结果代替对象的内容。

编写一段恢复代码(不常用)

  编写一段恢复代码,用它来拦截操作过程中发生的失败,以及使对象回滚到操作开始之前的状态上。这种方法主要用于永久性的(基于磁盘的)数据结构。

其他

  虽然失败原子性通常是可取的,但它并不总是可以实现的。例如,如果两个线程试图在没有适当同步的情况下并发地修改同一个对象,那么该对象可能会处于不一致的状态。因此,如果假定在捕捉到ConcurrentModificationException之后对象仍然可用,那就错了。错误是不可恢复的,所以方法在抛出AssertionError时,甚至不需要尝试保存失败原子性。

  即使在可能存在实现失败原子性的情况下,也并非总是可取的。 对于某些操作,它会显着增加成本或复杂性。 也就是说,一旦你意识到这个问题,通常都可以自由而轻松地做到失败原子性。

  总之,作为规则,任何生成的异常都是方法规范的一部分,应该使对象处于方法调用之前的状态。 违反此规则的地方,API文档应清楚地指出该对象将保留在哪种状态。遗憾的是,许多现有的API文档无法实现这一理想。

标签:状态,对象,构造,原子,失败,之前,软件,异常
来源: https://www.cnblogs.com/liwu7/p/16407304.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有