在我们的项目中,我们有一个类KnowledgeBaseManager,其他类使用它,如下所示:
KnowledgeBaseManager manager = KnowledgeBaseManager.get();
manager.foo();KnowledgeBaseManager包含一个静态变量standardKnowledgeBaseManager,该变量在第一次使用时会被初始化:
class KnowledgeBaseManager {
private static KnowledgeBaseManager standardKnowledgeBaseManager = null;
public static KnowledgeBaseManager get() {
if (standardKnowledgeBaseManager == null) {
standardKnowledgeBaseManager = new KnowledgeBaseManager();
// initialize standardKnowledgeBaseManager with appropriate knowledge base
}
return standardKnowledgeBase;
}此外,我们有一个参数化的构造函数。
public static KnowledgeBaseManager get(OntModel model) {...}到目前为止,我们只使用它进行单元测试,在单元测试中,我们需要一个在后台具有测试知识库的KnowledgeBaseManager。
现在,我们遇到了以下挑战:对于开发,我们希望应用程序使用一个知识库管理器,在后台使用另一个知识库(由于速度原因)。更具体地说,我们使用Wicket构建web应用程序。因此,我们希望在应用程序开始时的某个位置声明应用程序中使用的知识库和KnowledgeBaseManager (取决于我们是在开发还是部署中)。使用KB管理器的代码(如
KnowledgeBaseManager manager = KnowledgeBaseManager.get(); 现在)不应因此而更改。
问题是:最好的架构是什么?
我在考虑使用像PicoContainer或Guice这样的依赖注入框架,但我没有使用它的任何经验,我不确定这是否会对那个特定的问题产生额外的开销。对于我们的案例,有什么最佳实践的建议吗?
发布于 2011-10-20 04:01:17
您正在实现单例模式-如果您的代码是多线程的,那么您正在错误地实现它(参见http://java.sun.com/developer/technicalArticles/Programming/singletons/ )。
此外,正如您已经发现的,单例(即全局变量)不利于测试。依赖注入就是答案之一。首先忽略所有框架。这意味着你可以用传统的方式来编写你的KnowledgeBaseManager --一个有构造函数和方法的类,没有静态的单例方法。使用KnowledgeBaseManager的代码不会实例化或查找KnowledgeBaseManager-它会通过构造函数或setter方法接收它(我更喜欢前者):
public class ClassUsingKnowledgeBaseManager {
protected final KnowledgeBaseManager knowledgeBaseManager;
public ClassUsingKnowledgeBaseManager(KnowledgeBaseManager knowledgeBaseManager) {
this.knowledgeBaseManager = knowledgeBaseManager;
}
// ...
}请注意,假设该类不查找/实例化管理器,它并不关心您是否在使用单例或其他什么,并且您可以在测试中轻松地实例化不同的管理器,而无需以任何方式接触您的代码。
以这种方式构建代码后,您可能会发现最终得到的只是一些丑陋的大类,它们只是实例化您需要的所有对象,您需要一些额外的代码来将对象绑定到不同的作用域(即会话或请求作用域对象),并使用配置文件来控制实例化...如果您发现您正在编写大量重复或样板代码,您可以查看DI-frameworks,这可能会将您从这些代码中解救出来。
但是对于许多程序来说,您也许能够在不使用DI框架的情况下编写DI样式的代码。
发布于 2011-10-20 03:50:10
您可以使用构造性设计模式。
您可以创建一个工厂并将其配置为返回所需的对象。
https://stackoverflow.com/questions/7827149
复制相似问题