我的代码应该如何“防御性”?

时间:2023-01-14 07:49:05

I was having a discussion with one of my colleagues about how defensive your code should be. I am all pro defensive programming but you have to know where to stop. We are working on a project that will be maintained by others, but this doesn't mean we have to check for ALL the crazy things a developer could do. Of course, you could do that but this will add a very big overhead to your code.

我和我的一位同事正在讨论你的代码应该是多么具有防御性。我都是职业防守编程,但你必须知道在哪里停止。我们正在开发一个由其他人维护的项目,但这并不意味着我们必须检查开发人员可以做的所有疯狂事情。当然,你可以这样做,但这会给你的代码增加很大的开销。

How do you know where to draw the line?

你怎么知道在哪里划线?

15 个解决方案

#1


I don't know that there's really any way to answer this. It's just something that you learn from experience. You just need to ask yourself how common a potential problem is likely to be and make a judgement call. Also consider that you don't necessarily have to always code defensively. Sometimes it's acceptable just to note any potential problems in your code's documentation.

我不知道有什么办法可以回答这个问题。这只是你从经验中学到的东西。你只需要问问自己潜在的问题可能是多么普遍,并做出判断。还要考虑到你不一定总是要防御性地编码。有时,只需记下代码文档中的任何潜在问题即可。

Ultimately though, I think this is just something that a person has to follow their intuition on. There's no right or wrong way to do it.

但最终,我认为这只是一个人必须遵循他们的直觉。没有正确或错误的方法。

#2


Anything a user enters directly or indirectly, you should always sanity-check. Beyond that, a few asserts here and there won't hurt, but you can't really do much about crazy programmers editing and breaking your code, anyway!-)

用户直接或间接输入的任何内容,您都应该始终进行健全性检查。除此之外,一些断言在这里并且不会受到伤害,但无论如何,你无法对疯狂程序员编辑和破坏你的代码做太多的事情! - )

#3


I tend to change the amount of defense I put in my code based on the language. Today I'm primarily working in C++ so my thoughts are drifting in that direction.

我倾向于根据语言改变我在代码中放置的防御量。今天我主要是用C ++工作,所以我的想法正朝这个方向漂移。

When working in C++ there cannot be enough defensive programming. I treat my code as if I'm guarding nuclear secrets and every other programmer is out to get them. Asserts, throws, compiler time error template hacks, argument validation, eliminating pointers, in depth code reviews and general paranoia are all fair game. C++ is an evil wonderful language that I both love and severely mistrust.

在C ++中工作时,防御性编程就不够了。我把我的代码看作是在守护核秘密,而其他程序员都是为了得到它们。断言,抛出,编译器时间错误模板黑客,参数验证,消除指针,深度代码审查和一般偏执都是公平的游戏。 C ++是一种邪恶的语言,我既爱又严重不信任。

#4


I'm not a fan of the term "defensive programming". To me it suggests code like this:

我不是“防御性编程”一词的粉丝。对我来说它建议像这样的代码:

void MakePayment( Account * a, const Payment * p ) {
    if ( a == 0 || p == 0 ) {
       return;
    }
    // payment logic here
}

This is wrong, wrong, wrong, but I must have seen it hundreds of times. The function should never have been called with null pointers in the first place, and it is utterly wrong to quietly accept them.

这是错误的,错误的,错误的,但我必须已经看过数百次。永远不应该使用空指针调用该函数,并且静静地接受它们是完全错误的。

The correct approach here is debatable, but a minimal solution is to fail noisily, either by using an assert or by throwing an exception.

这里的正确方法是值得商榷的,但是最小的解决方案是通过使用断言或抛出异常来吵闹。

Edit: I disagree with some other answers and comments here - I do not think that all functions should check their parameters (for many functions this is simply impossible). Instead, I believe that all functions should document the values that are acceptable and state that other values will result in undefined behaviour. This is the approach taken by the most succesful and widely used libraries ever written - the C and C++ standard libraries.

编辑:我不同意其他一些答案和评论 - 我不认为所有功能都应该检查他们的参数(对于许多功能,这根本不可能)。相反,我相信所有函数都应记录可接受的值,并声明其他值将导致未定义的行为。这是最成功和最广泛使用的库所采用的方法 - C和C ++标准库。

And now let the downvotes begin...

现在让downvotes开始......

#5


If you're working on public APIs of a component then its worth doing a good amount of parameter validation. This led me to have a habit of doing validation everywhere. Thats a mistake. All that validation code never gets tested and potentially makes the system more complicated than it needs to be.

如果您正在处理组件的公共API,则值得进行大量参数验证。这导致我养成了在任何地方进行验证的习惯。这是一个错误。所有验证代码都没有经过测试,可能会使系统变得比它需要的更复杂。

Now I prefer to validate by unit testing. Validation definitely happens for data coming from external sources, but not for calls from non-external developers.

现在我更喜欢通过单元测试来验证。验证肯定发生在来自外部源的数据上,但不适用于来自非外部开发人员的调用。

#6


I always Debug.Assert my assumptions.

我总是Debug.Assert我的假设。

#7


My personal ideology: the defensiveness of a program should be proportional to the maximum naivety/ignorance of the potential user base.

我个人的意识形态:程序的防御性应该与潜在用户群的最大天真/无知成正比。

#8


Being defensive against developers consuming your API code is not that different from being defensive against regular users.

对开发人员使用API​​代码采取防御措施与防范普通用户并没有什么不同。

  • Check the parameters to make sure they are within appropriate bounds and of expected types
  • 检查参数以确保它们在适当的范围和预期类型内

  • Verify that the number of API calls which could be made are within your Terms of Service. Generally called throttling it usually only applies to web services and password checking functions.
  • 验证可以进行的API调用的数量是否在您的服务条款范围内。通常称为限制,它通常仅适用于Web服务和密码检查功能。

Beyond that there's not much else to do except make sure your app recovers well in the event of a problem and that you always give ample information to the developer so that they understand what's going on.

除此之外别无他法,除非确保您的应用程序在出现问题时能够很好地恢复,并且始终向开发人员提供充足的信息,以便他们了解正在发生的事情。

#9


Defensive programming is only one way of hounouring a contract in a design-by-contract manner of coding.

防御性编程只是以合同设计方式编写合同的一种方式。

The other two are

另外两个是

  • total programming and
  • 总编程和

  • nominal programming.

Of course you shouldnt defend yourself against every crazy thing a developer could do, but then you should state in wich context it will do what is expected to using preconditions.

当然,你不应该保护自己免受开发人员可以做的每一件疯狂的事情,但是你应该在上下文中说明它会做预期使用前置条件的事情。

//precondition : par is so and so and so 
function doSth(par) 
{
debug.assert(par is so and so and so )
//dostuf with par 
return result
}

#10


I think you have to bring in the question of whether you're creating tests as well. You should be defensive in your coding, but as pointed out by JaredPar -- I also believe it depends on the language you're using. If it's unmanaged code, then you should be extremely defensive. If it's managed, I believe you have a little bit of wiggleroom.

我想你必须提出你是否也在创建测试的问题。你的编码应该是防御性的,但正如JaredPar所指出的那样 - 我也相信这取决于你所使用的语言。如果它是非托管代码,那么你应该非常防守。如果它被管理,我相信你有一点点摆动。

If you have tests, and some other developer tries to decimate your code, the tests will fail. But then again, it depends on test coverage on your code (if there is any).

如果您有测试,并且其他一些开发人员试图破坏您的代码,则测试将失败。但话又说回来,它取决于代码的测试覆盖率(如果有的话)。

#11


I try to write code that is more than defensive, but down right hostile. If something goes wrong and I can fix it, I will. if not, throw or pass on the exception and make it someone elses problem. Anything that interacts with a physical device - file system, database connection, network connection should be considered unereliable and prone to failure. anticipating these failures and trapping them is critical

我尝试编写的代码不仅仅是防御性的,而是非常恶劣的。如果出现问题我可以解决它,我会的。如果没有,抛出或传递异常并使其成为别人的问题。任何与物理设备交互的东西 - 文件系统,数据库连接,网络连接都应该被认为是不可靠的并且容易出现故障。预测这些失败并将其捕获是至关重要的

Once you have this mindset, the key is to be consistent in your approach. do you expect to hand back status codes to comminicate problems in the call chain or do you like exceptions. mixed models will kill you or at least drive you to drink. heavily. if you are using someone elses api, then isolate these things into mechanisms that trap/report in terms you use. use these wrapping interfaces.

一旦你有了这种心态,关键是要在你的方法中保持一致。你希望交回状态代码来解决调用链中的问题,还是喜欢异常?混合型号会杀了你或者至少会让你喝酒。巨资。如果您正在使用elses api,那么将这些内容隔离到以您使用的术语陷阱/报告的机制中。使用这些包装界面。

#12


If the discussion here is how to code defensively against future (possibly malevolent or incompetent) maintainers, there is a limit to what you can do. Enforcing contracts through test coverage and liberal use of asserting your assumptions is probably the best you can do, and it should be done in a way that ideally doesn't clutter the code and make the job harder for the future non-evil maintainers of the code. Asserts are easy to read and understand and make it clear what the assumptions of a given piece of code is, so they're usually a great idea.

如果这里的讨论是如何针对未来(可能是恶意的或无能的)维护者进行防御性编码,那么你可以做的就是限制。通过测试覆盖和*使用断言你的假设来执行合同可能是你能做的最好的事情,并且它应该以理想的方式完成,不会使代码混乱,并使未来的非邪恶维护者的工作变得更加困难。码。断言易于阅读和理解,并清楚地表明给定代码片段的假设是什么,所以它们通常是个好主意。

Coding defensively against user actions is another issue entirely, and the approach that I use is to think that the user is out to get me. Every input is examined as carefully as I can manage, and I make every effort to have my code fail safe - try not to persist any state that isn't rigorously vetted, correct where you can, exit gracefully if you cannot, etc. If you just think about all the bozo things that could be perpetrated on your code by outside agents, it gets you in the right mindset.

防御性地针对用户操作进行编码完全是另一个问题,我使用的方法是认为用户出去接我。我会尽可能仔细地检查每个输入,并尽一切努力使我的代码安全无虞 - 尽量不要坚持任何未经严格审查的状态,尽可能纠正,如果不能,则优雅退出等等。你只需考虑外部代理可能在你的代码上执行的所有bozo事情,它就会让你处于正确的心态。

Coding defensively against other code, such as your platform or other modules, is exactly the same as users: they're out to get you. The OS is always going to swap out your thread at an inopportune time, networks are always going to go away at the wrong time, and in general, evil abounds around every corner. You don't need to code against every potential problem out there - the cost in maintenance might not be worth the increase in safety - but it sure doesn't hurt to think about it. And it usually doesn't hurt to explicitly comment in the code if there's a scenario you thought of but regard as unimportant for some reason.

防御性地针对其他代码(例如您的平台或其他模块)进行编码与用户完全相同:他们会帮助您。操作系统总是会在不合时宜的时候更换你的线程,网络总是会在错误的时间消失,而且一般来说,每个角落都会出现恶意。您不需要针对每个潜在问题进行编码 - 维护成本可能不值得增加安全性 - 但考虑到这一点肯定没有坏处。如果你想到一个场景但是由于某种原因认为不重要,那么在代码中明确注释通常没有什么坏处。

#13


Systems should have well designed boundaries where defensive checking happens. There should be a decision about where user input is validated (at what boundary) and where other potential defensive issues require checking (for example, third party integration points, publicly available APIs, rules engine interaction, or different units coded by different teams of programmers). More defensive checking than that violates DRY in many cases, and just adds maintenance cost for very little benifit.

系统应该具有良好设计的边界,其中发生防御性检查。应该确定用户输入在何处被验证(在什么边界)以及其他潜在防御性问题需要检查的位置(例如,第三方集成点,公共可用API,规则引擎交互或由不同程序员团队编码的不同单元) )。在许多情况下,违反DRY的防御性检查更多,并且只是为非常小的利益增加了维护成本。

That being said, there are certain points where you cannot be too paranoid. Potential for buffer overflows, data corruption and similar issues should be very rigorously defended against.

话虽如此,有些地方你不能太偏执。缓冲区溢出,数据损坏和类似问题的可能性应该得到非常严格的防范。

#14


I recently had scenario, in which user input data was propagated through remote facade interface, then local facade interface, then some other class, to finally get to the method where it was actually used. I was asking my self a question: When should be the value validated? I added validation code only to the final class, where the value was actually used. Adding other validation code snippets in classes laying on the propagation path would be too defensive programming for me. One exception could be the remote facade, but I skipped it too.

我最近有这样的场景,其中用户输入数据通过远程外观接口传播,然后是本地外观接口,然后是其他类,最终到达实际使用它的方法。我问自己一个问题:什么时候应该验证价值?我只将验证码添加到最终类中,其中实际使用了值。在传播路径上的类中添加其他验证代码片段对我来说太过防御性编程。一个例外可能是远程外观,但我也跳过它。

#15


Good question, I've flip flopped between doing sanity checks and not doing them. Its a 50/50

好问题,我在进行健全性检查和不进行检查之间徘徊。它是50/50

situation, I'd probably take a middle ground where I would only "Bullet Proof" any routines that are:

情况,我可能会采取中间立场,我只会“Bullet Proof”任何例程:

(a) Called from more than one place in the project

(a)从项目的多个地方打电话

(b) has logic that is LIKELY to change

(b)具有可以改变的逻辑

(c) You can not use default values

(c)您不能使用默认值

(d) the routine can not be 'failed' gracefully

(d)例程不能优雅地“失败”

Darknight

#1


I don't know that there's really any way to answer this. It's just something that you learn from experience. You just need to ask yourself how common a potential problem is likely to be and make a judgement call. Also consider that you don't necessarily have to always code defensively. Sometimes it's acceptable just to note any potential problems in your code's documentation.

我不知道有什么办法可以回答这个问题。这只是你从经验中学到的东西。你只需要问问自己潜在的问题可能是多么普遍,并做出判断。还要考虑到你不一定总是要防御性地编码。有时,只需记下代码文档中的任何潜在问题即可。

Ultimately though, I think this is just something that a person has to follow their intuition on. There's no right or wrong way to do it.

但最终,我认为这只是一个人必须遵循他们的直觉。没有正确或错误的方法。

#2


Anything a user enters directly or indirectly, you should always sanity-check. Beyond that, a few asserts here and there won't hurt, but you can't really do much about crazy programmers editing and breaking your code, anyway!-)

用户直接或间接输入的任何内容,您都应该始终进行健全性检查。除此之外,一些断言在这里并且不会受到伤害,但无论如何,你无法对疯狂程序员编辑和破坏你的代码做太多的事情! - )

#3


I tend to change the amount of defense I put in my code based on the language. Today I'm primarily working in C++ so my thoughts are drifting in that direction.

我倾向于根据语言改变我在代码中放置的防御量。今天我主要是用C ++工作,所以我的想法正朝这个方向漂移。

When working in C++ there cannot be enough defensive programming. I treat my code as if I'm guarding nuclear secrets and every other programmer is out to get them. Asserts, throws, compiler time error template hacks, argument validation, eliminating pointers, in depth code reviews and general paranoia are all fair game. C++ is an evil wonderful language that I both love and severely mistrust.

在C ++中工作时,防御性编程就不够了。我把我的代码看作是在守护核秘密,而其他程序员都是为了得到它们。断言,抛出,编译器时间错误模板黑客,参数验证,消除指针,深度代码审查和一般偏执都是公平的游戏。 C ++是一种邪恶的语言,我既爱又严重不信任。

#4


I'm not a fan of the term "defensive programming". To me it suggests code like this:

我不是“防御性编程”一词的粉丝。对我来说它建议像这样的代码:

void MakePayment( Account * a, const Payment * p ) {
    if ( a == 0 || p == 0 ) {
       return;
    }
    // payment logic here
}

This is wrong, wrong, wrong, but I must have seen it hundreds of times. The function should never have been called with null pointers in the first place, and it is utterly wrong to quietly accept them.

这是错误的,错误的,错误的,但我必须已经看过数百次。永远不应该使用空指针调用该函数,并且静静地接受它们是完全错误的。

The correct approach here is debatable, but a minimal solution is to fail noisily, either by using an assert or by throwing an exception.

这里的正确方法是值得商榷的,但是最小的解决方案是通过使用断言或抛出异常来吵闹。

Edit: I disagree with some other answers and comments here - I do not think that all functions should check their parameters (for many functions this is simply impossible). Instead, I believe that all functions should document the values that are acceptable and state that other values will result in undefined behaviour. This is the approach taken by the most succesful and widely used libraries ever written - the C and C++ standard libraries.

编辑:我不同意其他一些答案和评论 - 我不认为所有功能都应该检查他们的参数(对于许多功能,这根本不可能)。相反,我相信所有函数都应记录可接受的值,并声明其他值将导致未定义的行为。这是最成功和最广泛使用的库所采用的方法 - C和C ++标准库。

And now let the downvotes begin...

现在让downvotes开始......

#5


If you're working on public APIs of a component then its worth doing a good amount of parameter validation. This led me to have a habit of doing validation everywhere. Thats a mistake. All that validation code never gets tested and potentially makes the system more complicated than it needs to be.

如果您正在处理组件的公共API,则值得进行大量参数验证。这导致我养成了在任何地方进行验证的习惯。这是一个错误。所有验证代码都没有经过测试,可能会使系统变得比它需要的更复杂。

Now I prefer to validate by unit testing. Validation definitely happens for data coming from external sources, but not for calls from non-external developers.

现在我更喜欢通过单元测试来验证。验证肯定发生在来自外部源的数据上,但不适用于来自非外部开发人员的调用。

#6


I always Debug.Assert my assumptions.

我总是Debug.Assert我的假设。

#7


My personal ideology: the defensiveness of a program should be proportional to the maximum naivety/ignorance of the potential user base.

我个人的意识形态:程序的防御性应该与潜在用户群的最大天真/无知成正比。

#8


Being defensive against developers consuming your API code is not that different from being defensive against regular users.

对开发人员使用API​​代码采取防御措施与防范普通用户并没有什么不同。

  • Check the parameters to make sure they are within appropriate bounds and of expected types
  • 检查参数以确保它们在适当的范围和预期类型内

  • Verify that the number of API calls which could be made are within your Terms of Service. Generally called throttling it usually only applies to web services and password checking functions.
  • 验证可以进行的API调用的数量是否在您的服务条款范围内。通常称为限制,它通常仅适用于Web服务和密码检查功能。

Beyond that there's not much else to do except make sure your app recovers well in the event of a problem and that you always give ample information to the developer so that they understand what's going on.

除此之外别无他法,除非确保您的应用程序在出现问题时能够很好地恢复,并且始终向开发人员提供充足的信息,以便他们了解正在发生的事情。

#9


Defensive programming is only one way of hounouring a contract in a design-by-contract manner of coding.

防御性编程只是以合同设计方式编写合同的一种方式。

The other two are

另外两个是

  • total programming and
  • 总编程和

  • nominal programming.

Of course you shouldnt defend yourself against every crazy thing a developer could do, but then you should state in wich context it will do what is expected to using preconditions.

当然,你不应该保护自己免受开发人员可以做的每一件疯狂的事情,但是你应该在上下文中说明它会做预期使用前置条件的事情。

//precondition : par is so and so and so 
function doSth(par) 
{
debug.assert(par is so and so and so )
//dostuf with par 
return result
}

#10


I think you have to bring in the question of whether you're creating tests as well. You should be defensive in your coding, but as pointed out by JaredPar -- I also believe it depends on the language you're using. If it's unmanaged code, then you should be extremely defensive. If it's managed, I believe you have a little bit of wiggleroom.

我想你必须提出你是否也在创建测试的问题。你的编码应该是防御性的,但正如JaredPar所指出的那样 - 我也相信这取决于你所使用的语言。如果它是非托管代码,那么你应该非常防守。如果它被管理,我相信你有一点点摆动。

If you have tests, and some other developer tries to decimate your code, the tests will fail. But then again, it depends on test coverage on your code (if there is any).

如果您有测试,并且其他一些开发人员试图破坏您的代码,则测试将失败。但话又说回来,它取决于代码的测试覆盖率(如果有的话)。

#11


I try to write code that is more than defensive, but down right hostile. If something goes wrong and I can fix it, I will. if not, throw or pass on the exception and make it someone elses problem. Anything that interacts with a physical device - file system, database connection, network connection should be considered unereliable and prone to failure. anticipating these failures and trapping them is critical

我尝试编写的代码不仅仅是防御性的,而是非常恶劣的。如果出现问题我可以解决它,我会的。如果没有,抛出或传递异常并使其成为别人的问题。任何与物理设备交互的东西 - 文件系统,数据库连接,网络连接都应该被认为是不可靠的并且容易出现故障。预测这些失败并将其捕获是至关重要的

Once you have this mindset, the key is to be consistent in your approach. do you expect to hand back status codes to comminicate problems in the call chain or do you like exceptions. mixed models will kill you or at least drive you to drink. heavily. if you are using someone elses api, then isolate these things into mechanisms that trap/report in terms you use. use these wrapping interfaces.

一旦你有了这种心态,关键是要在你的方法中保持一致。你希望交回状态代码来解决调用链中的问题,还是喜欢异常?混合型号会杀了你或者至少会让你喝酒。巨资。如果您正在使用elses api,那么将这些内容隔离到以您使用的术语陷阱/报告的机制中。使用这些包装界面。

#12


If the discussion here is how to code defensively against future (possibly malevolent or incompetent) maintainers, there is a limit to what you can do. Enforcing contracts through test coverage and liberal use of asserting your assumptions is probably the best you can do, and it should be done in a way that ideally doesn't clutter the code and make the job harder for the future non-evil maintainers of the code. Asserts are easy to read and understand and make it clear what the assumptions of a given piece of code is, so they're usually a great idea.

如果这里的讨论是如何针对未来(可能是恶意的或无能的)维护者进行防御性编码,那么你可以做的就是限制。通过测试覆盖和*使用断言你的假设来执行合同可能是你能做的最好的事情,并且它应该以理想的方式完成,不会使代码混乱,并使未来的非邪恶维护者的工作变得更加困难。码。断言易于阅读和理解,并清楚地表明给定代码片段的假设是什么,所以它们通常是个好主意。

Coding defensively against user actions is another issue entirely, and the approach that I use is to think that the user is out to get me. Every input is examined as carefully as I can manage, and I make every effort to have my code fail safe - try not to persist any state that isn't rigorously vetted, correct where you can, exit gracefully if you cannot, etc. If you just think about all the bozo things that could be perpetrated on your code by outside agents, it gets you in the right mindset.

防御性地针对用户操作进行编码完全是另一个问题,我使用的方法是认为用户出去接我。我会尽可能仔细地检查每个输入,并尽一切努力使我的代码安全无虞 - 尽量不要坚持任何未经严格审查的状态,尽可能纠正,如果不能,则优雅退出等等。你只需考虑外部代理可能在你的代码上执行的所有bozo事情,它就会让你处于正确的心态。

Coding defensively against other code, such as your platform or other modules, is exactly the same as users: they're out to get you. The OS is always going to swap out your thread at an inopportune time, networks are always going to go away at the wrong time, and in general, evil abounds around every corner. You don't need to code against every potential problem out there - the cost in maintenance might not be worth the increase in safety - but it sure doesn't hurt to think about it. And it usually doesn't hurt to explicitly comment in the code if there's a scenario you thought of but regard as unimportant for some reason.

防御性地针对其他代码(例如您的平台或其他模块)进行编码与用户完全相同:他们会帮助您。操作系统总是会在不合时宜的时候更换你的线程,网络总是会在错误的时间消失,而且一般来说,每个角落都会出现恶意。您不需要针对每个潜在问题进行编码 - 维护成本可能不值得增加安全性 - 但考虑到这一点肯定没有坏处。如果你想到一个场景但是由于某种原因认为不重要,那么在代码中明确注释通常没有什么坏处。

#13


Systems should have well designed boundaries where defensive checking happens. There should be a decision about where user input is validated (at what boundary) and where other potential defensive issues require checking (for example, third party integration points, publicly available APIs, rules engine interaction, or different units coded by different teams of programmers). More defensive checking than that violates DRY in many cases, and just adds maintenance cost for very little benifit.

系统应该具有良好设计的边界,其中发生防御性检查。应该确定用户输入在何处被验证(在什么边界)以及其他潜在防御性问题需要检查的位置(例如,第三方集成点,公共可用API,规则引擎交互或由不同程序员团队编码的不同单元) )。在许多情况下,违反DRY的防御性检查更多,并且只是为非常小的利益增加了维护成本。

That being said, there are certain points where you cannot be too paranoid. Potential for buffer overflows, data corruption and similar issues should be very rigorously defended against.

话虽如此,有些地方你不能太偏执。缓冲区溢出,数据损坏和类似问题的可能性应该得到非常严格的防范。

#14


I recently had scenario, in which user input data was propagated through remote facade interface, then local facade interface, then some other class, to finally get to the method where it was actually used. I was asking my self a question: When should be the value validated? I added validation code only to the final class, where the value was actually used. Adding other validation code snippets in classes laying on the propagation path would be too defensive programming for me. One exception could be the remote facade, but I skipped it too.

我最近有这样的场景,其中用户输入数据通过远程外观接口传播,然后是本地外观接口,然后是其他类,最终到达实际使用它的方法。我问自己一个问题:什么时候应该验证价值?我只将验证码添加到最终类中,其中实际使用了值。在传播路径上的类中添加其他验证代码片段对我来说太过防御性编程。一个例外可能是远程外观,但我也跳过它。

#15


Good question, I've flip flopped between doing sanity checks and not doing them. Its a 50/50

好问题,我在进行健全性检查和不进行检查之间徘徊。它是50/50

situation, I'd probably take a middle ground where I would only "Bullet Proof" any routines that are:

情况,我可能会采取中间立场,我只会“Bullet Proof”任何例程:

(a) Called from more than one place in the project

(a)从项目的多个地方打电话

(b) has logic that is LIKELY to change

(b)具有可以改变的逻辑

(c) You can not use default values

(c)您不能使用默认值

(d) the routine can not be 'failed' gracefully

(d)例程不能优雅地“失败”

Darknight