Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java interfaces, the creator patterns and the "getInstance()" method or equivalent

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:

  1. A common Business Logic Layer.
  2. Platform-specific data layer (represented by the NoteDataStore interface)
  3. 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?

like image 839
curioustechizen Avatar asked Jul 25 '11 04:07

curioustechizen


People also ask

What is the use of getInstance () in Java?

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.

Why is getInstance static?

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.

Can I initialise interface in Java?

No, you cannot instantiate an interface. Generally, it contains abstract methods (except default and static methods introduced in Java8), which are incomplete.


1 Answers

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.

like image 162
Ivan Danilov Avatar answered Oct 06 '22 00:10

Ivan Danilov