2009-03-03 127 views
2

我要设计这个系统有两个主要组成部分的交换和输出逻辑:正在运行的系统

  1. 基地/核心员工。永不改变。
  2. 运行在核心上的东西。变化相当频繁。

这将在Java中开发,但问题适用于任何经典的OO语言。如何在运行的系统中替换上面的2而不重新编译1,并且在运行时不会停止1。可以重新编译2,但我不应该打扰1.

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

回答

6

没有更多的信息,它很难回答...但你可以检查出OSGi作为一些想法的起点。

+0

这听起来像是这种情况下的最佳方法。谢谢! – 2009-03-04 12:12:32

2

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

2

你会想为你经常变化的东西插件模式,再加上一些界面来重新启动插件。你的核心/基础(1)将负责动态加载包含你经常变化的东西的程序集/罐子(2)。

1

将源代码拆分为两棵树很容易。这些编译后的表单可以分开提供,非核心内容通过核心添加到-classpath进行编译。

代码可以在运行时通过类加载器加载(URLClassLoader.newInstance)。你必须小心让旧代码被卸载。你需要确保在任何地方绝对没有(强)引用。

2

这与servlet容器在处理servlet热插拔时的问题集完全相同。 Web服务器/容器应该连续运行,但必须能够按需加载新的servlet。

我建议您考虑看看Tomcat的源代码开始时(available via these subversion URLs。)

2

这基本上就是反射的。正如其他人所说,如果你遵循某种钩子或插件模式,这应该会让你获得最大的成功。基本上它是这样的:

  1. 在代码中创建定义良好的接口,描述核心应用程序与插件之间的契约。
  2. 想出一种方法来存储JAR /类信息在你的配置,这样就可以通过反射在运行时通过反射加载类型
  3. 加载插件,并呼吁在#描述的接口方法1

现在,如果您开始陷入工作流实施的困境,那么可能需要调查一下现成的工作流引擎。这里有太多要提到的,但Google搜索应该让你开始。

2

我曾经通过在Java之上使用JRuby完成了一些与您的目标类似的事情。核心部分使用Java,并且始终运行,Ruby脚本使用JRuby动态加载。这样,我可以在不重新启动(或编译)Java部分的情况下添加功能。

1

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

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

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