使用脚本实现设计和性能的平衡
2010-09-14 13:32:58 来源:WEB开发网简而言之,该模式建议您不要直接实例对象,而是将此操作封装在一个合适的 工厂方法中,从而使流程更具灵活性。假设在一个编译环境中,实现 Hello 的脚本被编译为了 HelloImpl 类。我不会研究如何在不同的环境中实现此操作,因为该内容不在本文的讨论范围之内。请看下面这个 Java 示例:
package net.scriptinginjava.invocable;
import java.io.FileReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class HelloFactory {
private boolean debug = true;
private ScriptEngine engine;
public HelloFactory(boolean debug) {
this.debug = debug;
ScriptEngineManager factory = new ScriptEngineManager();
engine = factory.getEngineByName("js");
}
public Hello getHello() throws Exception {
if (debug) {
System.out.println("scripted");
engine
.eval(new FileReader(
"src/net/scriptinginjava/invocable/interface.js"));
return ((Invocable) engine)
.getInterface(Hello.class);
} else {
System.out.println("compiled");
return new HelloImpl();
}
}
public static void main(String[] args) throws Exception {
HelloFactory client = new HelloFactory(true);
Hello hello = client.getHello();
hello.sayHello("World");
}
}
这个 Java 类代表一个工厂,负责实例化 Hello 接口的实现。这个示例还有一些重要的地方需要注意。首先,您会发现这个类有一个 debug 属性,用于判断是否应该执行某个脚本或实例化某个编译过的对象。该属性在类的构造函数中设置,在 getHello 方法中使用。
现在,如果运行此示例程序,则输出结果为:
scripted
Hello World
这表示我们通过执行脚本实例化了一对象。您可以尝试将 debug 参数的值修改为 false,然后再看看会发生什么。它的输出内容如下:
compiled
Hello World
通过这些技巧,我们实现了既定目标:即动态的开发环境和具有纯 Java 性能生产环境。当然, debug 参数只是一个简单的例子,您也可以使用适合自己开发环境的技巧(如 IoC 框架、属性文件配置等等),但是其中的基本原理是相同的。使用脚本实现接口,并获得动态语言的灵活性(比如说在运行时修改应用程序的功能)。完成之后,编译脚本并重新配置应用程序使用编译过的接口实现(一个纯 Java 类)。
上面所介绍的设计模式是可以在 Java 应用程序应用的许多基于脚本的设计模式的基础。许多“传统”设计模式的元素都适合使用脚本实现(不过您也可以找到特定于脚本环境的模式)。我在 Scripting in Java 这本书的 第 8 章 中讨论其中的一些模式。
结束语
谈到 Java 应用程序中的脚本语言时,有两个关键的问题是不可逃避的:它将对软件体系结构造成哪些影响?它将对软件的性能造成哪些影响?以 使用接口的设计原则为基础,并应用本文所介绍的这个简单的模式,我们可以成功地解决这两个问题。在其余的工作中,您只需选择最适合您编程需求的语言,并掌握在项目中使用脚本的时机的数量。
更多精彩
赞助商链接