我已经读过,异常不应该被用于指导您的应用程序的流程,但是应该用于将应用程序恢复到稳定的状态,当某些事情发生异常时,#34;异常"例如,当您无法连接到数据库时。
不应使用例外的示例是提供错误登录的用户。它不会是一个例外,因为它预计会发生这种情况。
我不确定以下情况是否例外:
我目前正在设计一个简单的博客。 A"帖子"被分配给一个"类别"。在我的帖子表中,我有一个带有外键约束的category_id字段。
现在,我正在使用Laravel,所以如果我尝试删除当前在其中有帖子的类别,我相信它应该因为外键约束而抛出\ Illuminate \ 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...
}
任何建议都将不胜感激。谢谢!
答案 0 :(得分:1)
这是非常基于意见的,所以我会给你我的意见: 例外是强大的,因为你可以附加大量的信息 - 你可以发送它们"向上调用堆栈"没有方法的hundrets检查任何调用的返回值并返回任何给他们自己的调用者。
这使您可以轻松处理callstack中所需图层的错误。
方法应该返回,调用的结果(即使它是无效的)。如果呼叫因任何原因失败,则应该否返回值。
错误不应该通过returnvalues传输,但有例外。
想象一个执行数据库查询的函数: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
,直到实现错误代码。第二种方式(另一种异常)会导致执行在callstack中某处出现未处理的异常。
处理错误传输的返回值(任何类型)都容易出错,错误可能会在某处消失,变成错误的错误"解释结果。
使用异常更安全:您要么使用返回值,要么具有(处理或未处理的)异常,但没有"错误的值"由于autocasts等。