Domanda

Vorrei iniziare ricordando che il mio problema deriva dal fatto che le interfacce in Java non consentono metodi statici. Ci sono state discussioni circa la ragione di questo su SO ( qui , per esempio). Quindi consente di non soffermarsi su questo. Sto cercando un modo per la mia interfaccia per creare un'istanza di se stesso (meglio, la sua implementazione) e tornare quello. A dispetto di giocare con pattern Singleton, Factory e modelli AbstractFactory, ancora non riesco a raggiungere il mio obiettivo.

Per approfondire quello che sto cercando - ecco la mia interfaccia:

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);
}

Ed ecco il mio livello di logica di business:

public class BusinessLogicLayer {

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

}

Ho cercato di utilizzare un modello di fabbrica in questo modo:

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.
         */
    }
}

Tuttavia, questo richiede ancora lo strato di business logic per conoscere la NoteDataStoreFactoryImpl classe di implementazione in tal modo:

NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();

Come faccio ad avere intorno a questo? Come faccio a mantenere la mia BusinessLogicLayer al buio per quanto riguarda la classe esatta implementazione da usare?


EDIT: Priorità dettagliata del mio problema

Alcune delle risposte suggeriscono l'uso di framework come Spring. Ahimè, non posso farlo perché questo target di applicazioni diverse piattaforme mobili (Android, Blackberry, JavaME). Avrei dovuto questo chiaro nella mia domanda iniziale -. Scuse per non farlo

La mia intenzione principale è quella di avere un app su più piattaforme. L'interfaccia utente, l'accesso al database, HTTP livelli di trasporto, ecc dovrà essere codificato appositamente per ogni piattaforma. Tuttavia, la logica di business è abbastanza semplice da giustificare uno strato comune per tutte le piattaforme. Ho intenzione di distribuire il livello di logica di business come una libreria JAR. Così anche, lo strato di analisi e framing (per JSON / XML).

C'è già stata una discussione su questo a SO (su se devo essere anche andando su questa strada) - Codice Logic riutilizzo . Tuttavia, supponendo che questo è OK e che procedere con l'approccio a più livelli e l'intenzione di avere uno strato comune nel codice. Ora, la mia situazione è tale che ho:

  1. Un comune Business Logic livello.
  2. strato dati specifici della piattaforma (rappresentata dalla interfaccia NoteDataStore)
  3. Platform-specifico strato di base Application (Controller, se posso chiamarlo così).

Si noti che se uso il modello di fabbrica o altro, posso permettermi di avere quello specifico livello per ogni piattaforma. Così, la fabbrica di metodo / classe stessa può conoscere la classe di implementazione NoteDataStore. Tuttavia, il livello Business Logic deve essere a conoscenza di una delle classi di implementazione.

Un uso tipico dei vari strati sarebbe come segue:

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();
    }
}

Eventuali ingressi su come gestire questo scenario?

È stato utile?

Soluzione 4

I infine, è andato per il suggerimento fornito da @Ray Tayek in un commento alla domanda iniziale. Ho semplicemente passare in un'istanza della NoteDataStore al momento della creazione del BusinessLogicLayer.

Questa semplice soluzione adatta alle mie esigenze abbastanza bene poiché non ho davvero bisogno di un Factory. Il mio obiettivo principale era per lo strato di BL di essere all'oscuro delle classi esatte di implementazione delle interfacce che utilizza. Ora, invece di una fabbrica, è il nucleo "Controller" strato che crea una concreta attuazione delle interfacce e li fornisce al livello di BL. Questo è semplicemente perfetto!

Ecco il frammento di codice.

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
    }

}

Altri suggerimenti

La classe dovrebbe accettare esempio fabbrica dall'esterno. Quando si crea un'istanza da soli -. A raggiungere nulla, lei ha ragione qui

Ci sono diverse tecniche qui. In generale, essi appartengono a qualcosa di molto generale indetto Inversion of Control o IOC in breve. Inoltre è utile conoscere 'Inversion of Control Contenitori' o IOCC. Java ha Primavera per esempio - leggere qui . Si dovrebbe chiedere ragazzi Java reali sugli altri:)

Anche dare un'occhiata a questo articolo .

Se si desidera tornare un'implementazione si potrebbe farlo con un classe anonima interna

NoteDataStore myImplementation = new NoteDataStore (){
//Implement methods here
};

Hai guardato IOC / Dependency Injection framework come Guice e la primavera? Essi possono essere troppo pesante per quello che stai cercando, ma sicuramente risolvere il problema che si descrive. Essi consentono tutto il codice livello di business da scrivere contro le interfacce e le implementazioni reali per essere definiti mediante il quadro IoC. Personalmente sono un grande fan di primavera e lo hanno utilizzato in quasi ogni applicazione Java che ho scritto negli ultimi anni 6+.

suggerisco di utilizzare framework di identificazione, come Guice e altri. Non è sufficiente utilizzare modello di fabbrica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top