我在MVC框架中编写了一些类似于:
的代码class Controller_Test extends Controller
{
public function action_index()
{
$obj = new MyObject();
$errors = array();
try
{
$results = $obj->doSomething();
}
catch(MyObject_Exception $e)
{
$e->getErrors();
}
catch(Exception $e)
{
$errors[] = $e->getMessage();
}
}
我的朋友认为Controller应该对MyObject一无所知,因此我不应该捕获MyObject_Exception。
他认为代码应该做这样的事情:
class Controller_Test extends Controller
{
public function action_index()
{
$obj = new MyObject();
$errors = array();
if($obj->doSomething())
{
$results = $obj->getResults();
}
else
{
$errors = $obj->getErrors();
}
}
我绝对理解他的方法,但感觉好像国家管理会导致意想不到的副作用。
什么是正确的或首选的方法?
编辑:错误地将$ obj-> getErrors()放在MyObject_Exception catch子句中而不是$ e-> getErrors();
答案 0 :(得分:1)
一般来说,我会说重要的是控制器是否理解异常的含义并且能够正确处理它。在许多情况下(如果不是大多数情况下),控制器将不知道如何正确处理异常,因此不应该捕获并处理它。
另一方面,可以合理地允许控制器理解某些特定异常,例如“DatabaseUnavailableException”,即使它不知道MyObject
如何或为什么使用数据库。可能会允许控制器重试MyObject
一次,但不知道MyObject
的实施方式。
答案 1 :(得分:1)
关于异常与返回错误代码的争论是漫长而血腥的。
他的论点在于,通过使用getErrors()函数,你学习有关对象的信息。如果这是你使用布尔返回表示成功的原因,那么你错了。为了使Controller能够正确处理错误,它必须知道它正在触摸的对象以及具体的错误是什么。这是网络错误吗?内存错误? 必须以某种方式了解。
我更喜欢异常模型,因为它更干净,允许我以更加可控的方式处理更多错误。它还为与要传递的例外相关的数据提供了明确的方法。
但是,我不同意你使用像getErrors()这样的函数。任何有助于我处理它的异常的数据都应包含在异常中。我不应该再去寻找对象来获取有关出错的信息。
网络连接超时了吗?该异常应包含它尝试连接的主机/端口,等待的时间以及来自较低网络级别的任何数据。
让我们在示例中执行此操作(在psuedo c#中):
public class NetworkController {
Socket MySocket = null;
public void EstablishConnection() {
try {
this.MySocket = new Socket("1.1.1.1",90);
this.MySocket.Open();
} catch(SocketTimeoutException ex) {
//Attempt a Single Reconnect
}
catch(InvalidHostNameException ex) {
Log("InvalidHostname");
Exit();
}
}
}
使用他的方法:
public class NetworkController {
Socket MySocket = null;
public Boolean EstablishConnection() {
this.MySocket = new Socket("1.1.1.1",90);
if(this.MySocket.Open()) {
return true;
} else {
switch(this.MySocket.getError()) {
case "timeout":
// Reattempt
break;
case "badhost":
Log("InvalidHostname");
break;
}
}
}
}
最终,您需要知道对象发生了什么,以了解如何响应它,并且使用一些复杂的if语句集或switch-case来确定它是没有意义的。使用例外并爱他们。
编辑:我不小心在后半句。答案 2 :(得分:1)
首先,控制器不是用于处理类引发的基础异常。
即使有人出现控制器,也应该停止在底层错误中说错了。
通过这种方式,我们确保控制器真正做到并且只做流控制工作。
为控制器提供一些输出的其他类应该没有错误,除非错误是特定于控制器的。