代码之家  ›  专栏  ›  技术社区  ›  Petar Minchev

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

  •  3
  • Petar Minchev  · 技术社区  · 16 年前

    假设我们在业务层中有以下方法。告诉ui层出了问题并给出错误消息的最佳实践是什么?方法应该在正常时返回空字符串,否则返回错误消息,还是应该在捕获代码中引发另一个异常来包装捕获的异常?如果我们选择第二个变体,那么ui应该进行另一次尝试,catch是太多的尝试,catch可能。这是第一个变体的伪代码。

    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 回复  |  直到 12 年前
        1
  •  1
  •   Nick Moore Wain    16 年前

    像这样返回字符串有点不寻常(但是没有 真实的 理由不太充分)。更常见的方法是:

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

    • 有一个void方法,它在失败时抛出异常,并在调用代码中处理它(如您所建议的那样)

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

        2
  •  5
  •   Joon    16 年前

    我喜欢从我的业务层返回一个标准的合同到我的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应用程序中)

    我最讨厌的是在一个网站上看到一个红色的标签(在那里我希望看到验证错误)和类似“数据库服务器拒绝了你的连接”的东西这是你只使用字符串返回错误数据运行的风险。

        3
  •  2
  •   Denis Bazhenov    16 年前

    最好的方法是用更一般的类型包装异常并重新抛出它。所以updateSameting()必须声明它可以抛出某种异常(例如:updateFaileDexception),并且在catch块中应该包装异常。

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

    但是捕获抽象异常类型不是一个好主意。你应该只包装那些你知道语义的东西。例如:sqlexception、dataaccessexception(spring dao)等。

    如果包装异常,则可以轻松包装nullpointerexception的interruptedexception。这会破坏你的申请。

        4
  •  0
  •   sth    12 年前

    最好的方法可能是有一个特定于层的自定义异常类,一旦您捕获了特定层中的异常,就将自定义异常抛出到调用层,这样做将具有以下优势。

    1. 您将得到更好的模块化方法来处理异常。
    2. 当您的代码复杂性增加时,代码的维护将很容易
    3. 您将对异常情况有更多的控制权

    例如,您捕获业务层中的异常并希望通知表示层

    public string DummyFunction
    {
       try
       {
    
       }
       catch(Exception ex)
       {
          throw new businessException();
       }
    }
    
    推荐文章