我读到异常不应该用于引导应用程序的流程,而应该用于在发生“异常”情况时将应用程序恢复到稳定状态,例如,当您无法连接到数据库时。
一个不应该使用异常的例子是用户提供了一个不正确的登录。这不会是一个例外,因为这是意料之中的事情。
我不确定以下情况是不是例外:
我目前正在设计一个简单的博客。一个“帖子”只分配给一个“类别”。在我的posts表中,我有一个带有外键约束的category_id字段。
现在,我使用的是Laravel,所以如果我试图删除一个当前有帖子的类别,我认为它应该抛出一个\Database\Database\QueryException,因为外键约束。因此,我应该依靠这一点并编写如下代码:
try {
$category->delete();
}
catch (\Illuminate\Database\QueryException $e) {
// Tell the user that they can't delete the category because there are posts assigned to it
}或者,既然我知道我想要我的博客是如何工作的,我应该使用:
if ($category->posts->isEmpty()) {
$category->delete();
}
else {
// Tell the user they can't delete...
}任何建议都将不胜感激。谢谢!
发布于 2016-11-24 01:45:51
它是基于观点的,所以我将给你我的观点:异常是强大的,因为你可以用它附加很多信息-你可以把它们“向上调用栈”,而不需要数百个方法检查任何调用的返回值,并将任何东西返回给它们自己的调用者。
这使您可以轻松地在callstack中的所需层处理错误。
一个方法应该返回,调用的结果是什么(即使它是void)。如果调用由于任何原因而失败,应该没有返回值。
错误不应该通过返回值来传输,而应该包含异常。
想象一个函数执行db查询:KeyAlreadyExistsException、InvalidSyntaxException和NullPointerException --很可能你想在代码中完全不同的部分来处理这些“错误”。
(一个是代码错误,一个是查询错误,一个是逻辑错误)
示例一,简单的“处理”:
try{
method1(1);
}catch (Exception $e){
//Handle all but NullpointerExceptions here.
}
---
method1($s){
try{
method2($s+2);
} catch (NullPointerException $e){
//only deal with NPEs here, others bubble up the call stack.
}
}
---
method2($s){
//Some Exception here.
}示例二--你可以看到所需的“嵌套”,这里的堆栈深度只有2。
$result = method1(1);
if ($result === 1){
//all good
}else{
//Handle all but NullpointerExceptions here.
}
---
method1($s){
$result = method2($s+2);
if ($result === 1){
return $result;
}else{
if ($result === "NullPointerException"){
//do something
}
}
method2($s){
//Exception here.
}特别是在维护方面,异常有巨大的优势:如果你添加一个新的“异常”--最坏的情况将是一个未处理的异常,但代码执行将中断。
如果你添加了新的“返回错误”,你需要确保每个调用者都知道这些新的错误:
function getUsername($id){
// -1 = id not found
$name = doQuery(...);
if (id not found) return -1;
else return $name;
}vs
function getUsername($id){
$name = doQuery(...);
if (id not found) throw new IdNotFoundException(...);
return $name;
}现在考虑这两种情况下的处理:
if (getUsername(4)=== -1) { //error } else { //use it }vs
try{
$name = getUsername(4);
//use it
}catch (IdNotFoundException $e){
//error
}现在,添加返回代码-2:在实现错误代码之前,第一种方法将假定用户名为-2。第二种方式(另一个异常)将导致执行停止,并在调用堆栈中的某个位置出现未处理的异常。
处理用于错误传输的返回值(任何类型)很容易出错,错误可能会消失在某个地方,变成“错误”的解释结果。
使用异常更安全:您可以使用返回值,也可以使用(已处理或未处理)异常,但没有由于自动转换等原因而导致的“错误值”。
https://stackoverflow.com/questions/40770303
复制相似问题