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?
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:
NoteDataStore
interface)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?
getInstance(String algorithm) The getInstance() method of java. security. Provider class is used to return a Signature object that implements the specified signature algorithm. This method traverses the list of registered security Providers, starting with the most preferred Provider.
for a singleton pattern, getInstance IS a static method, and uses static attrs. The whole point of static is to have things associated with the class instead of a specific object. The singleton pattern guarantees that you will have one instance of an object of that type.
No, you cannot instantiate an interface. Generally, it contains abstract methods (except default and static methods introduced in Java8), which are incomplete.
Your class should accept factory instance from the outside. When you're creating instance yourself - you achieve nothing, you are correct here.
There are several techniques here. In general they belong to something very general called Inversion of Control or IoC for short. Also it is useful to know about 'Inversion of Control Containers' or IoCC. Java has Spring for example - read here. You should ask real Java guys about others :)
Also take a look at this article.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With