3

我正在寻找一种使库可替换的方法。例如:我有一个通过多播管理通信的库。我在我的主应用程序中使用该库。我的想法是为此使用一个界面:

public interface MessageHandler {
    public void sendMessage();
    public Message receiveMessage();
}

现在应该可以更改库了。例如,通过广播管理通信的库。两者都实现了相同的接口。

所以在我的主要应用程序中,我希望有机会:

MessageHandler mHandler = new MulticastImpl();

或者

MessageHandler mHandler = new BroadcastImpl();

我的问题是:我在哪里放置接口定义?当我将它放入我的主应用程序时,我无法从库中看到它(因为库不知道主应用程序)。当我将它放入两个库时,我有两个不同的 MessageHandler 接口(例如 com.multicast.MessageHandler 和 com.broadcast.MessageHandler)

有任何想法吗?

4

6 回答 6

3

这是一个基本的插件系统。你应该做的是:

  1. 将插件 API 放在一个独立的 jar 中。
  2. 在主应用程序中包含这个插件 API jar。
  3. 插件实现不应包含插件 API(它们只会将其用于编译)。
  4. 为用户提供一种为插件指定“实现”类的方法(作为配置字符串)
  5. 在应用程序启动时,使用反射从配置中加载实现类。

注意,有更复杂的方法可以在 java 中加载插件(例如使用 java.util.ServiceLoader 和/或嵌套类加载器),但这是一个好的开始。

于 2012-07-21T14:00:34.507 回答
0

策略模式在这里可以提供帮助。

如果您希望库可替换,请定义一个封装该库功能的策略。

在代码中的任何地方,只需调用策略,而不是库。然后该策略将选择走哪条路。

完成后,您可以将封装的策略替换为任何其他策略或库。

有关策略模式的更多信息

于 2012-07-21T14:17:57.997 回答
0

您使用库接口,不要将它们放在两者上。图书馆正在定义用于与之通信的接口。

在您想要使用库接口进行编程的主应用程序上,您可以切换到它的不同实现,而无需更改代码,只需更改实现即可。

于 2012-07-21T13:58:33.973 回答
0

这个问题已经“回答”了,但无论如何,我想给你带来另一个视角。

您应该将 OSGi 和服务模块化作为实现相同服务逻辑实现的无缝替换的一种方式。OSGi 严格执行接口和实现的分离,并提供带有“捆绑包”的模块化架构,甚至可以在运行时(重新)部署。

您可以使用 MulticastMessageHandler 作为实现的“MessageHandler”服务。

例如,我们有一个数据存储,它有一个可切换的 noSQL 和一个 SQL 数据存储作为后端。应用程序永远不会注意到/不区分正在使用哪个。

Eclipse 具有 Equinox OSGi,它包含在您的 Eclipse 开发环境中。

于 2012-07-24T14:29:19.897 回答
0

您可以为此使用DI 。您将通过您最喜欢的 DI 实现注入实现。

于 2012-07-21T14:52:00.587 回答
0

有几种解决方案,但(将接口放在两个库中或将接口放在自己的库中),但您需要为接口指定一个名称,例如 com.messaging.MessageHandler。

于 2012-07-21T14:01:38.193 回答