【问题标题】:Decoupling from 3rd party library从 3rd 方库中解耦
【发布时间】:2017-08-06 20:54:15
【问题描述】:

我正在使用第三方 HTTP 客户端进行 GET、POST 调用。我不想将我的代码绑定到这个库。所以我决定创建一个名为 HttpClient 的接口和一个名为 HttpClientImpl 的实现。

接口中的方法之一是:

Response get(String url);

接口返回的响应对象是第三方库中的对象。所以这在技术上不会将我的代码与第三方库分离。

解耦自己的最佳方法是什么?我应该创建自己的响应对象来包装第三方库的响应吗?

【问题讨论】:

  • 你为什么不用T get(String)?然后,您可以在需要时将 Response 指定为类型参数。您还可以创建自己的包装类型。

标签: java interface wrapper decouple


【解决方案1】:

这是 Mediator 设计模式的一个经典案例: 使用 HTTP 客户端的类不应暴露给 HTTP 客户端实现(您已经封装)或其响应对象。

在这里使用泛型不会阻止使用类在这种情况下知道响应类。

正如你所建议的 - 有一个包装响应类/有一个从 3rd 方响应到你自己的转换器的转换器。

【讨论】:

    【解决方案2】:

    您是否考虑过抽象您通过 Http 访问的存储库,而不是抽象 http 库?例如,您有用于 Tweets 的 restful 端点:

    GET    https://someapi.com/Tweets
    GET    https://someapi.com/Tweets/{id}
    POST   https://someapi.com/Tweets
    PUT    https://someapi.com/Tweets/{id}
    DELETE https://someapi.com/Tweets/{id}
    

    有一个TweetRepository 类是有意义的,它可以创建、读取、更新和删除推文。这个类的接口可能如下所示:

    public interface TweetRepository {
        public List<Tweet> get();
        public int add(Tweet tweet);
        public void remove(int id);
        public Tweet get(int id);
        public void update(int id, Tweet tweet);
    }
    

    如果您的控制器使用该接口,那么您可以让您的实现使用您想要的任何 http 库,而无需引入耦合。

    【讨论】:

    • 这行得通。但是,如果 HTTP 库没有被抽象出来,存储库的底层实现仍然是紧密耦合的。
    • @tattihead 如果您想将所有代码与 3rdparty 库隔离开来,您的生活将会很悲惨。安德鲁的建议很好。 (除了大写方法名称的编码标准错误)。
    • 对不起,我最近一直在使用很多 C#。我不得不拒绝称它为ITweetRepository。 @tattihead 是的,http 实现将依赖于 some http 库,如果没有,如何实现?但是,当您将实现放在接口后面时,您会阻止使用该实现的代码与库耦合。您可以轻松地将其替换为连接到数据库的 TweetRepository,并改用 Sql。
    • @MeBigFatGuy - 考虑到您的服务中的几个模块正在使用您的 HTTP 客户端包装器 - 以防您返回一个与第 3 方 HTTP 客户端耦合的响应对象并且您需要修改所有在这些模块中......如果尽可能拥有最通用的 API,我将更多地谈论一般情况。
    • 是的,您可以抽象出接口背后的 http 实现。但是,除非您随后在上述存储库接口后面使用您的 http 抽象库,否则您已经将代码耦合到 http 协议,这(在我看来)比存储库实现耦合到特定的 http 库更糟糕。如果您必须合并使用不同 http 库的两个系统,我可以理解这是一个问题,但在大多数其他情况下,我会说这是不值得的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 2016-06-08
    相关资源
    最近更新 更多