码迷,mamicode.com
首页 > 其他好文 > 详细

软件构造 7-3 断言和防御性编程

时间:2019-05-21 00:13:32      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:最好   丢失   文件   容器   处理   软件   失败   做了   AMM   

    断言和防御性编程

目录回忆:设计和抽象数据类型

断言

  什么断什么不断

  使用断言的指导方针

防御性编程

  防御型编程的技巧

回忆

第一层防御:使bugs不可能

  最好的防御bug的方法就是在设计的时候就尽量避免bug

  - 静态检查:在编译的时候,可以抓住许多bug

  - 动态检查:比如数组溢出

  -  不变量:不变量

  -  防御性拷贝

  - 引用不变量:by final

第二种防御:

  如果bug不能被阻止,则限制在尽可能小的范围内

  问题越早发现,越容易被修复

技术图片

 

  利用assertion检查前置条件的满足性如上图,抛出异常

  检查前置条件是防御性编程的一种方式

断言

什么是?

断言用于运行时检查代码的正确性

每个断言都有一个boolean表达式(你认为正确)

如果不正确,JVM会抛出AssertionError。

断 言要优于if-else语句:1.对程序中的假设起到适当的文档作用;2.在实 际运行时不会带来性能问题(在实现运行时断言可被禁止)。

断言通常需要两个参数(也可以只有表达式)

-一个正误表达式,假设其为正确的

-message表示如果失败的信息

为什么?

 测试 不变性是否保持,同时起到了文档说明作用

验证编程者的理解

提高程序的无bug自信

使黑盒测试变为白盒

能被用于验证

  内部不变量

  类不变量

  控制流不变量

  方法的前置条件

  方法的后置条件

什么去断什么不断?

  用

   输入值是否在指定的范围内

   文件或流是否打开关闭

   文件或流的读写控制

   读入参数是否被修改

   是否为空指针

   数组长度

   Table已经初始化去包含真实值

   容器类是否为空或者为满

   两个结果是否匹配

   (开发时用来帮助发现错误,分布时禁用)

  不用

   断言不是免费的,需要慎用

   可以信任的内容比如x+1

   不要用断言来测试外部情况,文件是否存在,输入正确性,网络是否可用,断言用于检测内部的内容

   外部导致的不是bug程序无法预测和控制,外部应该用exception机制来处理

在开发过程中打开断言。

  java默认关闭断言。建议,如果对性能影响不大,可以在发布版本中保留

  技术图片

注意这里的断言和Junit的测试里面的断言方法不一样,这里是用来正文中使用的。

断言的使用原则

  断言和异常机制:

    断言使正确性(处理不该发生的)

    异常时健壮性(不知道什么时候发生的)

  Exception处理错误的输入 数据,断言检查bugs 

  断言在大型复杂程序和高可靠性程序中特别有用

  运行时关闭断言

  断言用于前置和后置条件(Use Assertions for pre-/post- conditions )

真实世界的程序和项目往往太杂乱,不能完全依 靠断言。

 防御性编程

  防御性编程是防御性设计的一种形式,旨 在确保在不可预见情况下软件持续提供功能的能力

   主要思想:如果某个方法被传入了不良数据,即使这 是另一个子程序的错误,方法本身也不会受到破坏。 

    (就像开车,不管别人做了怎样危险的事,你要保证自己的安全避让或正常行驶)

   优点

      提升代码质量

      使代码更加可以理解

      软件在可以预测的情况下运行,不管其他程序怎么样1

防御性编程的技巧

  技术图片包括了了前面的的断言和异常处理

 

1.在出现了无效的输入

    输入垃圾,输出垃圾(这样不好)。我们从不输出垃圾,不管他输入的是不是垃圾  

    检查外部输入的数据

    检查每个常规的参数

    决定如何处理不好的输入

2.隔栏

    隔栏是一种容损策略 ,起到防火墙的作用(对进来的数据进行消毒,对错误敏感反应)

    One way to barricade for defensive programming purposes is to designate certain interfaces as boundaries to “safe” areas.Check data crossing the boundaries of a safe area for validity and respond sensibly if the data isn’t valid. 

    类的public方法中假设数据是 不安全的,他们负责检查和清洗;private方法则认为被公有方法接收 处理后的数据是安全的。 

    类似于手术室管理,进入之前消毒,之后认为安全 

    在输入时将输入数据转换为适当的类型

   隔栏的实现可以体现断言和异常的区别

    外部隔栏使用错误(异常)处理

    内部隔栏使用断言

  隔栏的使用也展示了在架构级别如何处理错误,决定哪些代码位于 内部,哪些位于隔栏之外是架构级决策

3.bug急救(Debugging Aids)调试助手(见7.4)

   不要把产品版的限制强加于开发版之上 

    在开发过程中牺牲速度和对资源的使用,以换取可以使开发更顺利的内置 工具。

    使用进攻式编程 :对异常的处理:在开发阶段让异常尽可能明 显的展示出来,而在产品运行时让异常能够自我恢复。 --进攻式编程 

    尽可能使程序失败 ,Sometimes the best defense is a good offense(最好的防御是进攻),开发时失败地越严重,发布后失败地越轻微。

    做好计划,避免调试用代码和程序代码纠缠不清。 

      - 使用版本控制和生成工具,如make

      - 使用内置的预处理器。

    编写你自己的的预处理器

      - 如果该语言不包含的话

    使用调试存根(不知道在说什么看完7.4再说)

开发中,希望错误尽可能明显;发布后,希望错误尽可能 不明显。

    保留检查重要错误的代码 :确定程序的哪些部分能够承受未检测 出错误而造成的后果,哪些不能。 

    删除检查琐碎错误的代码 : 如果错误的后果微不足道,可以删除检测代码 |并不是物理删除 ,要利用版本控制或者make工具 

    删除导致硬崩溃的代码:会造成严重错误的调试代 码(如数据丢失),应该被移除 

    保留帮助优雅退出的代码:如果程序包含检测潜在致命错误的调试代码,可将这些调 试代码保留,以使程序稳妥的崩溃。 

    日志错误和友好错误消息:考虑在产品代码中留下调试代码,但改变他们的行为,以便适合 生产版本。如在产品中禁用断言,但把断言转换为将消息记录入日志中。确保您留下的错误消息是友好的。 

 

 

   

考虑在产品代码中留下调试代码,但改变他们的行为,以便适合 生产版本。如在产品中禁用断言,但把断言转换为将消息记录入日志中。

 

软件构造 7-3 断言和防御性编程

标签:最好   丢失   文件   容器   处理   软件   失败   做了   AMM   

原文地址:https://www.cnblogs.com/hitycy/p/10897424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!