2011-10-19 73 views
1

在我们的项目,我们有一个类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。

现在,我们有以下挑战:为了发展,我们希望该应用程序使用KB-经理在后台另一个知识基础(因为速度)。更具体地说,我们用Wicket构建一个Web应用程序。因此,我们希望在应用程序,其中的知识基础和KnowledgeBaseManager在应用程序中使用(根据wheter我们在开发或部署)开始申报地方。使用KB管理器的代码(如

KnowledgeBaseManager manager = KnowledgeBaseManager.get(); 

现在)不应该为此而改变。

的问题是:什么是对,最好的架构?

我在考虑使用像PicoContainer或Guice这样的依赖注入框架,但没有任何经验,我不确定这是否会成为特定问题的开销。有关我们案例最佳实践的任何建议?

回答

2

您所用的单图案 - 如果你的代码是多线程的,要实现它错了(见http://java.sun.com/developer/technicalArticles/Programming/singletons/

而且,你也已经发现,单身人士(即全局变量)是测试。依赖注入是答案之一。首先忽略所有框架。这意味着你可以用传统的方式编写你的KnowledgeBaseManager--一个带有构造函数和方法的类,没有静态的singletonish-factorish方法。使用KnowledgeBaseManager代码并实例化或查找的KnowledgeBaseManager-它,而通过构造函数或setter方法接收它(我更喜欢前者):

public class ClassUsingKnowledgeBaseManager { 

    protected final KnowledgeBaseManager knowledgeBaseManager; 

    public ClassUsingKnowledgeBaseManager(KnowledgeBaseManager knowledgeBaseManager) { 
    this.knowledgeBaseManager = knowledgeBaseManager; 
    } 

    // ... 

} 

注意,因为类不查找/实例化管理,它并不关心你是使用单例还是什么,并且你可以很容易地在你的测试中实例化一个不同的管理器,而不用以任何方式触及你的代码。在你以这种方式构造你的代码之后,你可能会发现你最终会遇到一些丑陋的类,它们只是实例化所有你需要的对象,你需要一些额外的代码来把对象绑定到不同的作用域(例如会话或请求 - 并使用配置文件来控制实例...如果您发现您正在编写大量重复或样板代码,则可以查看DI框架,这可能会为您节省时间。

但是对于很多程序,您可能可以在不使用DI框架的情况下编写DI样式的代码。

0

你可以使用的结构设计模式。

您可以创建一个工厂,并配置它返回你所需要的对象。