Java接口,创建者模式和"getInstance()"方法或等效方法

cur*_*zen 5 java design-patterns abstract-factory

我想首先提一下,我的问题源于Java中的接口不允许静态方法.有关SO的原因的讨论(例如,这里).所以不要纠缠于此.我正在寻找一种方法让我的界面创建自己的实例(而不是它的实现)并返回它.尽管使用了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);
}
Run Code Online (Sandbox Code Playgroud)

这是我的业务逻辑层:

public class BusinessLogicLayer {

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

}
Run Code Online (Sandbox Code Playgroud)

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

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.
         */
    }
}
Run Code Online (Sandbox Code Playgroud)

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

NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?对于要使用的确切实现类,如何让我的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

关于如何处理这种情况的任何输入?

Iva*_*lov 5

你的班级应该从外面接受工厂实例.当你自己创建实例时 - 你什么都没做,你在这里是正确的.

这里有几种技术.一般来说,它们属于一般称为控制反转或简称IoC的东西.了解"控制容器的反转"或IoCC也很有用.Java以Spring为例 - 请阅读此处.你应该向真正的Java人询问其他人:)

另外看看这篇文章.


cur*_*zen 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
    }

}
Run Code Online (Sandbox Code Playgroud)