5

我想首先提到我的问题源于 Java 中的接口不允许静态方法这一事实。已经在 SO 上讨论了这个原因(例如, here)。因此,让我们不再赘述。我正在为我的接口寻找一种方法来创建它自己的实例(而不是它的实现)并返回它。尽管使用了 Singleton 模式、Factory 和 AbstractFactory 模式,我仍然无法实现我的目标。

详细说明我正在尝试的内容 - 这是我的界面:

public interface NoteDataStore {
    public boolean deleteNote(long noteId);
    public boolean addNote(Note note);
    public List<Note> listNotes();
    public boolean editNote(long noteId, Note note);
    public List<Note> search(String searchString);
}

这是我的业务逻辑层:

public class BusinessLogicLayer {

    public BusinessLogicLayer(){
        /*
         * GOAL: To get an instance of NoteDataStore here,
         *  without being aware of the implementation class.
         */
    }

}

我尝试使用这样的工厂模式:

public interface NoteDataStoreFactory {
    public NoteDataStore getDataStoreInstance();
}

public class NoteDataStoreFactoryImpl implements NoteDataStoreFactory{
    public NoteDataStore getDataStoreInstance(){
        return NoteDataStoreImpl.getInstance();
        /*
         * Here, NoteDataStoreImpl is an implementation of NoteDataStore.
         * This should be transparent to my business logic layer.
         */
    }
}

但是,这仍然需要业务逻辑层知道实现类NoteDataStoreFactoryImpl,因此:

NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();

我该如何解决这个问题?如何让我的 BusinessLogicLayer 对要使用的确切实现类一无所知?


编辑:我的问题的更详细背景

一些答案建议使用像 Spring 这样的框架。唉,我不能这样做,因为这个应用程序针对各种移动平台(Android、Blackberry、JavaME)。我应该在我最初的问题中明确说明这一点 - 很抱歉没有这样做。

我的主要目的是拥有一个跨平台的应用程序。UI、数据库访问、HTTP 传输层等必须专门针对每个平台进行编码。但是,业务逻辑足够简单,可以保证跨所有平台的通用层。我打算将业务逻辑层分发为 JAR 库。解析和框架层(用于 JSON/XML)也是如此。

在 SO 已经讨论过这个问题(关于我是否应该走这条路)——逻辑代码重用。但是,假设这没问题,并且我继续使用分层方法并打算在代码中使用一个通用层。现在,我的情况是这样的:

  1. 一个通用的业务逻辑层。
  2. 平台特定的数据层(由NoteDataStore接口表示)
  3. 特定于平台的应用程序核心层(控制器,如果我可以这样称呼它)。

请注意,如果我使用工厂模式或其他类似模式,我可以负担得起每个平台特定的层。所以,工厂方法/类本身可以知道NoteDataStore实现类。但是,业务逻辑层必须不知道任何实现类。

各种层的典型用法如下:

public class NoteDataStoreAndroid implements NoteDataStore{

    public boolean deleteNote(long noteId){
        /*
         * Android-specific database code
         */
    }

    /* ... similarly, other methods */
}


public class AndroidCoreApp{

    public void doBusinessLogic(){
        BusinessLogicLayer businessLogic = new BusinessLogicLayer();
        businessLogic.startBusinessLogic();
    }
}

关于如何处理这种情况的任何意见?

4

5 回答 5

5

你的类应该接受来自外部的工厂实例。当您自己创建实例时 - 您什么也没做,您在这里是正确的。

这里有几种技术。一般来说,它们属于非常笼统的东西,简称为控制反转或 IoC。了解“控制容器的反转”或 IoCC 也很有用。Java 有 Spring 例如 -在这里阅读。你应该向真正的 Java 人询问其他人:)

也看看这篇文章

于 2011-07-25T04:38:44.590 回答
2

如果你想返回一个实现,你可以使用匿名内部类

NoteDataStore myImplementation = new NoteDataStore (){
//Implement methods here
};
于 2011-07-25T04:32:58.357 回答
0

你看过像 Guice 和 Spring 这样的 IoC/依赖注入框架吗?对于您要寻找的东西,它们可能太重了,但它们绝对可以解决您描述的问题。它们允许针对接口编写所有业务层代码,并通过 IoC 框架定义实际实现。我个人是 Spring 的忠实粉丝,在过去 6 年多的时间里,我几乎在所有我编写的 Java 应用程序中都使用了它。

于 2011-07-25T04:41:13.400 回答
0

我终于在对原始问题的评论中接受了@Ray Tayek 提供的建议。我只是在NoteDataStore创建BusinessLogicLayer.

这个简单的解决方案非常适合我的需求,因为我并不真正需要工厂。我的主要目标是让 BL 层不知道它使用的接口的确切实现类。现在,它不是工厂,而是核心“控制器”层,它创建接口的具体实现并将它们提供给 BL 层。这简直太完美了!

这是代码片段。

public class NoteDataStoreAndroid implements NoteDataStore{

    public boolean deleteNote(long noteId){
        /*
         * Android-specific database code
         */
    }

    /* ... similarly, other methods */
}


public class AndroidCoreApp{

    public void doBusinessLogic(){
        BusinessLogicLayer businessLogic = new BusinessLogicLayer(new NoteDataStoreAndroid());
        businessLogic.startBusinessLogic();
    }
}

public class BusinessLogicLayer {

    private NoteDataStore mDataStore;
    public BusinessLogicLayer(NoteDataStore dataStore){
        this.mDataStore = dataStore;

        //Do something useful with mDataStore
    }

    public void startBusinessLogic(){
        //Do something useful with mDataStore
    }

}
于 2011-07-27T06:27:16.107 回答
0

建议你使用 ID 框架,如 Guice 等。不是简单地使用工厂模式。

于 2017-01-17T01:27:43.777 回答