Liskov替换原则(LSP),代理模式和异常

时间:2015-02-13 10:32:38

标签: design-patterns exception-handling liskov-substitution-principle

假设我有一个接口和客户端代码使用的具体实现。现在,使用实现此接口的代理模式,我可以通过网络路由对接口发出的请求。网络连接当然可能会失败,这可能会引发异常。

使用该接口的客户端代码将获得意外的异常。我想在这种情况下违反了LSP原则。

但是,如果不允许它们传播出界面,那么如何处理网络异常呢?

这里有一些Java代码来澄清我的意思:

interface Interface
{
    abstract void method1();
    abstract void method2();
    abstract void method3();
}

class Implementation implements Interface
{
    void method1();
    void method2();
    void method3();
}

class ProxyOverNetwork implements Interface
{
    // I can't add the NetworkException as it is not part of the Interface 
    // and would violate LSP, but how to handle the network problems then,
    // when the ProxyOverNetwork might not be the right place to do so?

    void method1() throws(NetworkException);
    void method2() throws(NetworkException);
    void method3() throws(NetworkException);
}

我是否必须更改接口以允许异常传播出来?

1 个答案:

答案 0 :(得分:0)

鉴于你是用Java编写的,如果你希望你的Interface以某种方式实现,方法调用可能会失败,你需要做两件事之一:

  • 更改Interface的方法,以便它们引发已检查的异常,或
  • 使实现引发未经检查的异常。

在SO和整个互联网上详细讨论了已检查和未检查的异常的相对优势和劣势。几年前我没有写过很多Java,但几年前趋势是只使用未经检查的异常,以避免调用者处理它们的麻烦。诚实的Ruby人(我是其中一员)会告诉你,由于他们的无类型语言,他们忘记一直处理错误案例,并最终在修补程序中处理它们。 Haskell现在很流行,这种语言使用类型签名来限制行为,使得未经检查的例外营地为山丘大喊大叫。

我会使用已检查的异常来确保调用者处理可能的失败。但是,我不会使用NetworkException,而是像MethodFailureException这样的通用内容(如果我们知道Interface我们可以选择更好的名称)NetworkException可以扩展。这样可以避免调用者了解实现,同时仍允许他们处理错误。