I would like to start off by mentioning that my problem stems from the fact that interfaces in Java do not allow static methods. There have been discussions about the reason for this on SO (here , for example). So lets not dwell on that. I am looking for a way for my interface to create an instance of itself (rather, its implementation) and return that. In spite of playing around with Singleton pattern, Factory and AbstractFactory patterns, I still cannot achieve my goal.
To elaborate on what I'm trying - here's my interface:
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);
}
And here's my business logic layer:
public class BusinessLogicLayer {
public BusinessLogicLayer(){
/*
* GOAL: To get an instance of NoteDataStore here,
* without being aware of the implementation class.
*/
}
}
I tried to use a factory pattern like so:
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.
*/
}
}
However, this still requires the Business Logic layer to know the implementation class NoteDataStoreFactoryImpl
thus:
NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();
How do I get around this? How do I keep my BusinessLogicLayer in the dark regarding the exact implementation class to use?
EDIT: More Detailed Background of my problem
A few of the answers suggest the use of frameworks like Spring. Alas, I cannot do so because this application targets various mobile platforms (Android, Blackberry, JavaME). I should have made this clear in my original question - apologies for not doing so.
My main intention is to have an app across platforms. The UI, database access, HTTP transport layers etc will have to be coded specifically for each platform. However, the business logic is simple enough to warrant a common layer across all platforms. I intend to distribute the business logic layer as a JAR library. So also, the parsing and framing layer (for JSON/XML).
There has already been a discussion about this at SO (on whether I should even be going down this path) - Logic Code reuse. However, assuming this is OK and that I proceed with the layered approach and the intention to have one layer common in code. Now, my situation is such that I have:
- A common Business Logic Layer.
- Platform-specific data layer (represented by the
NoteDataStore
interface) - Platform-specific Application core layer (Controller, if I may call it so).
Note that if I use the Factory pattern or other such, I can afford to have that layer specific to each platform. So, the factory method/class itself can know about the NoteDataStore
implementation class. However, the Business Logic Layer must be unaware of any of the implementation classes.
A typical use of the various layers would be as follows:
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();
}
}
Any inputs on how to handle this scenario?