简体   繁体   English

添加标志以引发异常是不好的做法吗?

[英]Is it bad practice to add a flag to throw an exception?

I have some methods in a class that I think could be useful for testing stuff, but also in some cases the program may want to halt completely if the check fails. 我认为在类中有一些方法可以用来测试内容,但在某些情况下,如果检查失败,程序可能想要完全停止。 Originally I was wrapping the method calls in if conditions and then throwing an exception, however, I ended up having the same if conditions in many methods and it seemed wasteful, so I added a boolean flag to the check method to have it throw an exception if the check failed. 最初我在条件调用中包装,然后抛出一个异常,但是,我最终在许多方法中使用相同的if条件而且看起来很浪费,所以我在check方法中添加了一个布尔标志,让它抛出一个异常如果检查失败。 An example: 一个例子:

public function isValidDirection($direction, $throwException = false) {
    if(!in_array($direction, $this->getDirections()) && $throwException) {
        throw new \InvalidArgumentException(sprintf('Invalid direction value. Valid directions are: "%s"', implode(", ", $this->getDirections())));
    }    

    return in_array($direction, $this->getDirections());
}

Is this a bad idea? 这是一个坏主意吗? I've not come across this kind of pattern before and I'm wondering are there any pitfalls to it? 我之前没有遇到过这种模式,我想知道它有什么陷阱吗?

An exception should be thrown in exceptional circumstances. 在特殊情况下应该抛出异常。 That means when your code is in a situation that it is not prepared to handle. 这意味着当您的代码处于不准备处理的情况时。 If your function is a validation function whose job it is to confirm the validity of data, there should hardly be any exceptional error possible. 如果您的函数是验证函数,其作用是确认数据的有效性,则几乎不会出现任何异常错误。 The job of the function is simple: take input, return true or false depending on whether it's valid. 函数的工作很简单:接受输入,返回truefalse具体取决于它是否有效。 If you want to handle the case of invalid input by throwing an exception and you want to DRY that repetitive check, create another function which wraps your validation function. 如果您想通过抛出异常来处理无效输入的情况并且想要干掉那个重复检查,那么创建另一个包装验证函数的函数。 So you'd have two functions: isValidDirection($input) and assertIsValidDirection($input) , the latter of which throws an exception if it's not valid and otherwise does nothing. 所以你有两个函数: isValidDirection($input)assertIsValidDirection($input) ,如果它无效则抛出异常,否则什么都不做。

function isValidDirection($input) {
    return ...; // true or false
}

function assertIsValidDirection($input) {
    if (!isValidDirection($input)) {
        throw new InvalidArgumentException;
    }
}

This keeps both functions' responsibilities clear and their implementation simple. 这使得两个职能部门的职责明确,实施简单。

Yeah, it's a bad idea. 是的,这是一个坏主意。 If the method gets into a state where it can't continue or otherwise shouldn't get into it should throw an exception. 如果方法进入无法继续或不应该进入的状态,则应抛出异常。 It's up to the calling code to handle the exception as it feels is necessary or let the program crash. 这取决于调用代码来处理异常,因为它感觉是必要的或让程序崩溃。 Otherwise the caller is oblivious to the program failing and will continue and usually make the situation worse/harder to debug. 否则调用者无视程序失败并将继续并且通常使情况变得更糟/更难调试。

If, in the case that you don't want to halt your program you can catch the exception and log an error, or handle it some more graceful way depending on your situation. 如果在您不想暂停程序的情况下,您可以捕获异常并记录错误,或者根据您的具体情况以更优雅的方式处理它。 If you don't expect the error at all the program will crash (ideally during testing) and the error won't propagate; 如果您不希望所有程序中的错误都会崩溃(理想情况下在测试期间)并且错误不会传播; you then know exactly where to look to fix it. 然后你就知道确切的修复方向。

So, if I understand it correctly, your code should throw an exception if the $direction isn't in getDirections . 因此,如果我理解正确,如果$direction不在getDirections ,则代码应抛出异常。

eg: 例如:

public function isValidDirection($direction) {
    if(!in_array($direction, $this->getDirections())) {
        throw new \InvalidArgumentException(sprintf('Invalid direction value. Valid directions are: "%s"', implode(", ", $this->getDirections())));
    }    

    return in_array($direction, $this->getDirections());
}

(Also, you don't need to call getDirections 3 times, just call it once and store it in a variable) (此外,您不需要调用getDirections 3次,只需调用一次并将其存储在变量中)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM