防御性编程

来自计算思维百科
跳转至: 导航搜索
防御性编程.png

防御性编程是一种细致、谨慎的编程方法,是防御式设计的一种具体体现,它是为了保证,对程序的不可预见的使用,不会造成程序功能上的损坏。

基本概念

软件滥用者形形色色,从利用程序小缺陷的不守规则的用户,到想尽办法非法进入他人系统的职业黑客。有太多的程序员在不经意间为这些人留下了可随意通过的后门。随着网络化计算机的兴起,粗心大意所带来的后果变得愈来愈显著了。许多大型软件开发公司终于意识到了这种威胁,开始认真思考这个问题,将时间和资源投入到严谨的防御性编码工作中。事实上,在受到恶意进攻之后才亡羊补牢是很困难的。为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能地“保护”自己。我们通过明确地在代码中对设想进行检查,击碎了未记录下来的设想。这是一种努力,防止我们的代码以将会展现错误行为的方式被调用。

防御性编程有助于程序的安全性,可以防范诸如此类恶意的滥用。黑客和病毒制造者常常会利用那些不严谨的代码,以控制某个应用程序,然后实施他们蓄意的破坏计划。这对软件开发的现代世界而言,无疑是个严重的威胁;这个问题涉及到诸如生产效率、金钱和个人隐私等方方面面。

防御性编程是一种编程习惯,是指预见在什么地方可能会出现问题,然后创建一个环境来测试错误,当预见的问题出现的时候通知你,并执行一个你指定的防止损害动作。防御性编程是一种防卫方式,而不是一种补救形式。

应用防御性编程技术,你可以侦测到可能被忽略的错误,防止可能会导致灾难性后果的“小毛病”的出现,在时间的运行过程中为你节约大量的调试时间。防御性编程使我们可以尽早发现较小的问题,而不是等到它们发展成大的灾难的时候才发现。

防御性编程并不能排除所有的可能错误,但是它会减少麻烦的出现并易于修正。

使用方法及步骤

计算机并不是知晓一切的,计算机并不知道运行到何处会出现错误,是人通过编写程序告诉计算机如何进行加法如何执行与处理,所以也是人告诉计算机可能会出现的错误并且教计算机在面对这些错误的时候可以采取的方案。

1、通过采用良好的编程风格,来防范大多数编码错误

如选用有意义的变量名,或者审慎地使用括号,都可以使编码变得更加清晰了,并减少缺陷出现的可能性。在投入到编码工作之前,先考虑大体的设计方案。

2、不要仓促地写代码

在考虑好可能会出现什么错误、会有什么样的逻辑分支、怎么样写才能减少缺陷再开始写代码。   

3、不要相信任何人

用怀疑的眼光审视所有的输入和所有的结果,直到你能证明它们是正确的为止。

麻烦可能来自于:

真正的用户意外地提供了假的输入,或者错误地操作了程序;恶意的用户,故意造成不好的程序行为;客户端代码使用的参数调用了你的函数,或者提供了不一致的输入;运行环境没有为程序提供足够的服务;外部程序库运行失误,不遵从你所依赖的接口协议;

4、编码的目标是清晰,不只是简洁。

5、不要让任何人做让他们不该做的修补工作

将所有变量保持在尽可能小的范围内。不到万不得已,不要声明全局变量。如果变量可以声明为函数内的局部变量,就不要再文件范围上声明。如果变量可以声明为循环体内的局部变量,就不要再函数范围上声明。

6、检查所有的返回值

如果一个函数返回一个值,它这样做肯定是由理由的。大多数难以察觉的错误都是因为程序员没有检查返回值而出现的。无论如何,都要在适当的级别上捕获和处理相应的异常。

7、审慎地处理内存(和其他宝贵的资源)

8 、使用安全的数据结构
如果你做不到,那么就安全地使用危险的数据结构。
最常见的安全隐患大概是由缓冲溢出引起的。缓冲溢出是由于不正确地使用固定大小的数据结构而造成的。如果你的代码在没有检查一个缓冲的大小之前就写入这个缓冲,那么写入的内容总是有可能会超过缓冲的末尾的。

9、在声明的位置上初始化所有的变量

10、尽可能推迟一些声明变量

使变量的声明位置与使用它的位置尽量接近,从而防止它干扰代码的其他部分。不要再多个地方重用同一个临时变量,变量重用会使以后对代码重新完善的工作变得异常复杂。

11、审慎地进行强制转换

如果你真的想使用强制转换,就必须对之深思熟虑。你所告诉编译器的是:“忘记类型检查吧,我知道这个变量是什么,而你不知道。”你在类型系统中撕开了一个大洞,并直接穿越过去。这样做很不可靠。

12、其他

提供默认的行为

遵从语言的习惯

检查数值的上下限

正确设置常量

应用案例

应用1-避免0被除

案例:如果在程序执行过程中进行除法,并且除数是0,执行将会停止并显示一条错误信息。在这种情况下,我们称程序崩溃了。

解决步骤:此时为了防止这一类错误,我们要使用选择结构进行编程,当除数可能为0的时候我们将提示除数不能为0,安全的结束这个程序,防止程序崩溃。 

应用2-约会女朋友的异常情况处理

案例:情人节到了,小李准备买一束玫瑰花送个女朋友,然后一起吃顿饭。正常的流程应该是预定酒店→买玫瑰花→坐车到酒店→与女朋友共进晚餐。但是防御性编程的思想是要考虑到个步骤可能出现的异常,并进行处理。例如买花时发现没有玫瑰花了,防御性编程要求小李预先想好买百合花,如果花店的花卖完了,小李要考虑买一个巧克力;坐车的时候如果长时间公交车不来,效率要考虑后备方案做出租车;如果小李的女朋友很长时间没有到,小李要考虑怎么联系女朋友等等。在整个过程中,小李对各个环节的异常情况都进行了预估,并进行相应处理,这就是一种防御性编程的思想,其目的就是为了使与女友共进晚餐的事情顺利进行。

可以体现的计算思维

防御性编程体现了计算思维中的容错纠错特点。在防御性编程的思想下,我们根据经验对可能存在的异常进行预估,并设计相应的处理方案,是问题顺利得到解决。