3天前,在阅读了很多关于使用OOP的优点后,我开始使用类作为练习在OOP中重写我的一个脚本。
现在我很困惑天气我应该使用例外与否。他们似乎让我的工作更努力,更长久。
我的应用程序检查数据是否是通过Ajax请求发送的,然后通过脚本使用该信息。
检查此示例:
/*
* The older way
*/
if($ajaxEnabled) {
$error = errorWrap('Ajax error');
} else {
$error = errorWithBackLinkWrap('NoAjax error');
}
function doSomething() {
if(empty($POST['name'])) {
die($error);
}
}
/*
* OOP way
*/
class someClass {
private $_ajaxEnabled;
public function doSomething() {
try {
if(!$this->_isDateValid()) {
if($this->$_ajaxEnabled) {
throw new ajaxException('Ajax error');
} else {
throw new noAjaxException('NOAjaxError');
}
}
} catch(ajaxException $e) {
echo $e->getErrorMessage();
} catch(noAjaxException $e) {
echo $e->getErrorMessage();
}
}
}
此代码仅用于演示问题,因此我知道其中有一些未定义的函数:)。
所以在开始之前,错误处理对我来说更容易,因为我只需要回应相应的错误。
现在使用异常,在每个函数中我必须首先检查连接类型,然后为每个抛出的异常编写2个catch函数,这会产生更大的代码。
我在php中对OOP很陌生,所以也许有一个更清洁,更好的方法来做到这一点,是吗?
答案 0 :(得分:8)
你的问题并不少见,是否/什么时候使用例外有时是一个哲学决定,许多有经验的开发人员无法围绕它。
话虽如此,我发现列出每种处理错误方式的不同属性可以很容易地选择您喜欢的方式:
0
是成功还是失败?)何时使用:这很明显。当您信任调用者时使用返回代码(内部代码或可以安全忽略的普通错误)。
try/catch
)何时使用:如果您不信任您的呼叫者(第三方)或真的需要确保您的错误代码不会被忽略
何时使用:通常很明显。你需要立即停止一切。
(在PHP环境中,我认为它没有多大区别。上述建议仍应适用。)
(除了)
通常情况下,当发生不良事件时(特别是当您学习的第一种编程语言是PHP:P时)写出错误信息很诱人。但是如果你真的想要理解OOP,那么这不是处理错误的正确方法。
理想情况下,每个对象或每个函数只能执行一个函数。如果一个函数将错误写入屏幕并且做了自己的事情,那么以后很难切换到DatabaseErrorLogger
或TextFileErrorLogger
等。一种方法是提供记录器使用(这称为依赖注入)。另一种方法是使用异常 - 这样,调用者可以选择使用哪个ErrorLogger
。
答案 1 :(得分:4)
当您的代码可以使用if语句正常处理错误时,您不应该使用异常(就像您在示例中所做的那样)。
例外情况适用于特殊情况。不幸的是,这不是很简单,所以由程序员来决定是的例外与否。我认为一个好的经验法则是:
避免使用例外来表明 可合理的条件 预计作为典型的一部分 该方法的功能。
来自:http://www.codeproject.com/KB/dotnet/When_to_use_exceptions.aspx
答案 2 :(得分:4)
作为错误处理机制的异常在概念和实现方面与函数返回代码非常不同。你不能/不应该简单地将一个映射到另一个。在继续进行之前,您应该先阅读并摘要this article(以及其他一些内容,包括this one*)。
如果您希望使用异常而不是错误报告/处理的返回代码,那么代码的结构应该会发生显着变化。
(* CodeProject链接是特定于.NET的,但是代码很少。它主要是一篇易于应用于任何语言的最佳实践文章。)
答案 3 :(得分:2)
异常的有用性不在于打印错误代码。这是捕捉错误,所以你可以尝试解决它们,而不是与烟花爆炸。
答案 4 :(得分:2)
如果我理解你是怎么做的,我认为你做错了。没有错误的例外情况。它们适用于特殊情况。错误可能意味着任何数量的事情(例如,用户没有在注册表单上输入足够长的用户名)。这本身不应该是一个例外。但是,您可以使用例外来证明注册本身失败(视具体情况而定)......
并且您不需要在每个级别都有try / catch块。事实上,这是不好的做法。如果您可以处理异常,或者在让异常继续之前需要执行其他操作,则仅捕获异常。因此,例如:如果您要连接到一组远程网站,并且第一个网站失败。您可以捕获该异常,并使用第二个网站重试。并继续前进,直到你不再离开(此时你会抛出另一个例外,表明没有网站可以被提取)。另一个例子是如果你正在生成图像。你有一个方法在生成抛出异常的图像时进行一些计算。您将要捕获该异常,以便您可以从映像进程中“清理”(以节省内存等),然后在完成后重新抛出它:catch (ImageSomethingException $e) { /* Clean up here */ throw $e; }
...
异常的真正威力在于它可以让你处理你想要的情况(因为异常只能冒泡到程序的顶部)。但是只捕获您知道可以处理它们的异常(或者至少需要清理)。您几乎不应该在生产代码中执行print $e->getMessage()
。
就个人而言,我总是安装一个default exception handler。基本上,如果未捕获异常,它将记录该异常,然后生成500错误页面。这让我可以专注于我可以在代码中处理的异常,而不是试图抓住所有东西(这通常不是一个好主意)......
祝你好运......答案 5 :(得分:1)
我个人讨厌例外。我不在我的应用程序中使用它们。我更喜欢函数返回(和期望)定义的状态代码,并处理该级别上的可恢复错误。
在真正异常的情况下(如无法访问的数据库服务器,文件I / O错误等)是紧急情况,我倾向于触发并处理致命错误。 (对象关闭仍将发生,因此只要将它们放在destructor functions中,任何需要关闭等的连接仍将被处理。)
第三方图书馆的例外情况我努力尽快抓住,并以自己的方式处理它们。
Joel Spolsky在他臭名昭着的Exceptions essay中提出了比我更好的理由。
请注意,这是一种观点和一种思想流派。有很多出色的软件,其错误处理完全基于异常,这非常好。关键是一致性 - 要么你做出设计决定来使用它们,要么你做不到。
答案 6 :(得分:1)
大多数开发过程都有一个有限的容量 - 即使可以预测代码可能运行的所有可能情况(即所有可能的输入组合,支持系统的所有可能状态,如数据库,DNS,现有数据)等)然后处理每个场景都是不切实际的。使用例外允许您:
将一系列操作捆绑到一个实体中,以确定整体成功/失败
使用一位代码处理多种不同的故障模式
所以是的 - 我会说异常处理是一种有用的做法 - 但不是替代专门用于处理常见故障模式,智能和信息性(并且类型化异常是恕我直言,完全矛盾)
答案 7 :(得分:0)
如果只需要显示错误信息,为什么不使用
catch (Exception $e)
{ print ($e->getMessage()); }
答案 8 :(得分:0)
它的开发人员打电话..不是强制性的,因为kizzx2告诉。 但是如果你正在编写一些类或库类的类,那么它总是很好的抛出异常,因为将来可能会被其他人使用。或者