应用程序中各层之间的通信

时间:2010-03-27 08:09:37

标签: language-agnostic exception-handling layer

假设我们在业务层中有以下方法。告诉UI层出错的最佳做法是什么,并给出错误消息?该方法是否正常时返回一个空字符串,否则返回错误消息,或者它应该在包含捕获的异常的catch代码中抛出另一个异常?如果我们选择第二个变体,那么UI应该有另一个尝试,抓住哪个太多尝试,抓住可能。这是第一个变体的伪代码。

public String updateSomething()
{
   try
   {
      //Begin transaction here
      dataLayer.do1();
      dataLayer.do2();
      dataLayer.doN();
      //Commit transaction code here
   }
   catch(Exception exc)
   {
      //Rollback transaction code here
      return exc.message;
   }

   return "";
 }

这是一个好习惯还是我应该在catch中抛出另一个异常(那么方法将无效)?

4 个答案:

答案 0 :(得分:5)

我喜欢从我的业务层返回标准合约到我的UI图层。

看起来像这样:

public class ServiceOperationResult<T>
{

    public bool Successful
    {
        get; 
        set;
    }

    public ServiceErrorType ErrorType
    {
        get;
        set;
    }

    public string ErrorMessage
    {
        get;
        set;
    }

    public T ReturnData
    {
        get;
        set;
    }
}

我使用泛型,以便每个服务都可以定义它发回的内容,标准错误标志告诉客户端应用程序发生了什么类型的错误(这些是元类型,如“内部错误”,“外部方错误” ,“业务规则验证错误”)然后应用程序可以以标准方式对这些错误类型做出反应。

例如,业务错误显示在红色错误标签中,而内部错误会重定向到错误页面(在Web应用程序中)或关闭表单(在Windows应用程序中)

我的宠物讨厌在网站上看到一个红色标签(我希望看到验证错误)并看到类似“数据库服务器拒绝您的连接”这样的风险,您只能使用字符串返回来运行错误数据。

答案 1 :(得分:2)

最好的方法是在一些更通用的类型中包装异常并重新抛出它。因此updateSomething()必须声明它可以抛出某种异常(例如:UpdateFailedException),并且在catch块中你应该包装异常。

public String updateSomething() {
  try {
    [...]
  } catch ( SQLException e ) {
    // rollback;
    throw new UpdateFailedException(e);
  }
}

但是捕获抽象异常类型并不是一个好主意。你应该只包装那些你知道的语义的东西。例如:SQLException,DataAccessException(Spring DAO)等。

如果你包装Exception,你很容易包装NullPointerException的InterruptedException。这可能会破坏你的申请。

答案 2 :(得分:1)

返回像这样的字符串有点不寻常(但是没有真正的原因)。更常用的方法是:

  • 返回一个布尔值,并有一些设置错误消息的方法,通过记录它,设置一些全局“最后错误”值,或者有一个指向传递给你的方法的错误构造的指针更新;

  • 有一个void方法,在失败时抛出异常,并在调用代码中处理它(如你所知)

我已经看到上述两种用法都被广泛使用了。很难说哪个是“最好的”。尝试与您正在使用的语言的习语和惯例和/或您正在使用的现有代码集/库(如果有)保持一致。

答案 3 :(得分:0)

可能最好的方法是拥有一个特定于图层的自定义异常类,一旦你在特定图层中捕获异常就会将自定义异常抛给调用图层,这将带来以下优势。

  1. 您将获得更好的模块化方法来处理异常。
  2. 当您的代码复杂性增加时,代码的维护将很容易
  3. 您将对异常情况有更多控制权
  4. 例如,您在业务层中捕获异常并想要通知表示层

    public string DummyFunction
    {
       try
       {
    
       }
       catch(Exception ex)
       {
          throw new businessException();
       }
    }