在正在运行的系统上交换逻辑

时间:2009-03-03 16:26:16

标签: java design-patterns oop

我想设计这个有两个主要组成部分的系统:

  1. 基础/核心东西。永远不要改变。
  2. 在核心上运行的东西。经常变化。
  3. 这将在Java中开发,但问题适用于任何经典的OO语言。如何在正在运行的系统中替换2以上而不重新编译1,并且在运行时甚至不停止1。重新编译2是可以的,但我不应该打扰1。

    有没有设计模式可以做到这一点?我认为这有点类似于插件行为,但2实际上对应用程序的工作至关重要,而不仅仅是附加组件。

8 个答案:

答案 0 :(得分:6)

如果没有更多信息,很难回答......但您可以查看OSGi作为某些想法的起点。

答案 1 :(得分:2)

我们需要更多信息来解决这个问题。如果你在谈论在运行时加载全新的逻辑,那可能会非常困难。如果您正在谈论只是交换实现,可以使用策略模式轻松完成。

答案 2 :(得分:2)

你需要一个插件模式,用于频繁更改的东西,再加上一些用于重新启动插件的界面。你的核心/基础(1)将负责动态加载包含你经常变化的东西的组件/罐子(2)。

答案 3 :(得分:2)

这正是servlet容器在处理servlet热交换时遇到的问题。 Web服务器/容器应该连续运行,但必须能够按需加载新的servlet。

我建议你先看看Tomcat源代码(available via these subversion URLs)。

答案 4 :(得分:2)

这基本上就是反思。正如其他人所说的那样,如果你遵循某种钩子或插件模式,这应该会让你大部分时间。基本上它是这样的:

  1. 在代码中创建定义良好的接口,描述核心应用和插件之间的合约。
  2. 设计一种在配置中存储jar / class信息的方法,以便您可以在运行时通过反射加载类型
  3. 通过#1
  4. 中描述的接口上的反射和调用方法加载插件

    现在,如果您开始陷入工作流实施的困境,那么可能是时候研究一个现成的工作流引擎了。这里有太多值得一提但谷歌搜索应该让你入门。

答案 5 :(得分:2)

我曾经在Java上使用JRuby做过类似于你的目标的事情。核心部分是Java,并且一直在运行,Ruby脚本是使用JRuby动态加载的。这样,我可以在不重新启动(或编译)Java部分的情况下添加功能。

答案 6 :(得分:1)

将源代码分成两棵树很容易。这些编译形式可以单独提供,编译核心的非核心内容添加到-classpath。

可以在运行时使用类加载器(URLClassLoader.newInstance)加载代码。您必须小心将旧代码卸载。你需要确保在任何地方都没有(强)引用它。

答案 7 :(得分:1)

显然,这正是为Eclipse这样的东西开发的东西;他们使用OSGi构建了一个插件框架。

那就是说,我会选择一种可以在JVM,Rhino / JavaScript或JRuby等JVM上运行的脚本语言。 Spring等框架现在支持the ability to define beans in these languages并让它们动态重新编译。

随着对动态语言(在JDK6脚本之上)的更多支持到达JVM,这些可能会在未来被广泛采用。