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上已经讨论过这个问题(关于我是否应该走这条路) - 逻辑代码重用.但是,假设这是正常的,我继续使用分层方法,并打算在代码中使用一个层.现在,我的情况是这样的:
NoteDataStore界面表示)请注意,如果我使用工厂模式或其他类型,我可以负担得到每个平台特定的图层.因此,工厂方法/类本身可以了解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)
关于如何处理这种情况的任何输入?
我最终采纳了@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)