最喜欢的(聪明的)防御性编程最佳实践 [英] Favorite (Clever) Defensive Programming Best Practices

查看:82
本文介绍了最喜欢的(聪明的)防御性编程最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您必须选择防御性编码的最喜欢的(聪明)技术,那将是什么?尽管我目前使用的语言是Java和Objective-C(具有C ++背景),但可以使用任何语言进行回答.除了我们这里70%以上的人已经知道的防御技术之外,这里还要重点介绍聪明"防御技术.因此,现在该深入了解您的绝招了.

换句话说,除了这个无趣示例之外,请尝试思考其他问题:

  • if(5 == x) 代替 if(x == 5):以避免意外分配

以下是一些有趣的最佳防御性编程实践的示例(特定于语言的示例在Java中):

-锁定变量,直到您知道需要更改它们为止

也就是说,您可以声明 all 所有变量final,直到您知道需要更改它为止,此时可以删除final.一个普遍未知的事实是,这对于方法参数也有效:

public void foo(final int arg) { /* Stuff Here */ }

-发生不良情况时,请留下大量证据

发生异常时,您可以执行许多操作:显然,将其记录下来并执行一些清理工作是很简单的.但是,您也可以留下一些证据(例如,在调试器中将变量设置为"UNABLE TO LOAD FILE"或99999这样的前哨值将很有用,以防您碰巧遇到异常catch -block).

-在一致性方面:细节决定成败

与您正在使用的其他库保持一致.例如,在Java中,如果要创建一个提取值范围的方法,则使下限为 inclusive 和上限为 exclusive .这将使其与以相同方式操作的String.substring(start, end)之类的方法保持一致.在Sun JDK中,您会发现所有这些类型的方法都具有这种行为,因为它会进行各种操作,包括与数组一致的元素迭代,其中索引的范围是从零( inclusive )到长度( exclusive )的数组.

那么您最喜欢的防御方法是什么?

更新:如果您还没有,请随时加入.在选择官方答案之前,我有机会获得更多反馈.

解决方案

在每个没有默认大小写的switch语句中,我添加了一个带有错误消息的中止程序的案例.

 #define INVALID_SWITCH_VALUE 0

switch (x) {
case 1:
  // ...
  break;
case 2:
  // ...
  break;
case 3:
  // ...
  break;
default:
  assert(INVALID_SWITCH_VALUE);
}
 

If you had to choose your Favorite (clever) techniques for defensive coding, what would they be? Although my current languages are Java and Objective-C (with a background in C++), feel free to answer in any language. Emphasis here would be on clever defensive techniques other than those that 70%+ of us here already know about. So now it is time to dig deep into your bag of tricks.

In other words try to think of other than this uninteresting example:

  • if(5 == x) instead of if(x == 5): to avoid unintended assignment

Here are some examples of some intriguing best defensive programming practices (language-specific examples are in Java):

- Lock down your variables until you know that you need to change them

That is, you can declare all variables final until you know that you will need to change it, at which point you can remove the final. One commonly unknown fact is that this is also valid for method params:

public void foo(final int arg) { /* Stuff Here */ }

- When something bad happens, leave a trail of evidence behind

There are a number of things you can do when you have an exception: obviously logging it and performing some cleanup would be a few. But you can also leave a trail of evidence (e.g. setting variables to sentinel values like "UNABLE TO LOAD FILE" or 99999 would be useful in the debugger, in case you happen to blow past an exception catch-block).

- When it comes to consistency: the devil is in the details

Be as consistent with the other libraries that you are using. For example, in Java, if you are creating a method that extracts a range of values make the lower bound inclusive and the upper bound exclusive. This will make it consistent with methods like String.substring(start, end) which operates in the same way. You'll find all of these type of methods in the Sun JDK to behave this way as it makes various operations including iteration of elements consistent with arrays, where the indices are from Zero (inclusive) to the length of the array (exclusive).

So what are some favorite defensive practices of yours?

Update: If you haven't already, feel free to chime in. I am giving a chance for more responses to come in before I choose the official answer.

解决方案

In every switch statement that doesn't have a default case, I add a case that aborts the program with an error message.

#define INVALID_SWITCH_VALUE 0

switch (x) {
case 1:
  // ...
  break;
case 2:
  // ...
  break;
case 3:
  // ...
  break;
default:
  assert(INVALID_SWITCH_VALUE);
}

这篇关于最喜欢的(聪明的)防御性编程最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆