Come faccio a strutturare le interfacce quando gli oggetti usano solo una parte dell'interfaccia?

9

Ho un progetto in cui ho due classi che richiedono entrambi un oggetto di accesso al database che aggiorni la stessa tabella. I vincoli del framework e del progetto fanno sì che non possa combinare queste due classi. Ho creato un caso qui sotto che mostra come è il setup. La classe A deve essere in grado di aggiornare e leggere il record, mentre la classe B deve essere in grado di aggiornare ed eliminare il record.

Se uso le classi così come sono, funziona perfettamente, ma sto avendo un problema con questo fatto che ciascuna delle classi richiede funzionalità che non sta utilizzando per essere implementate. Ad esempio, per usare la classe A, devo passargli un dao che implementa la funzione delete, anche se non verrà mai chiamata. Allo stesso modo, devo passare la classe B a dao che implementa la funzione di lettura ma non verrà mai chiamata.

Ho pensato di approcciarlo avendo interfacce che ereditassero gli altri (IReadDao, IUpdateDao, IDeleteDao da cui sarebbe stato ereditato), ma questo approccio richiederebbe fondamentalmente un'interfaccia diversa per ogni combinazione di funzioni (IUpdateAndRead, IReadAndDelete, IReadAndUpdate ...)

Voglio usare un'interfaccia per il dao perché non voglio accoppiare l'applicazione con il database. C'è uno schema o un metodo per realizzare ciò che voglio che qualcuno sappia? Grazie in anticipo.

class IDao {

  void update(ModelDao model);
  void delete(String guid);
  ModelDao read(String guid);

}

Class A {

  private IDao dao;

  public A(IDao dao) {

    this.dao = dao;

  }

  public void doStuff() {

    ModelDao model = new ModelDao();

    ...

    dao.update(model);

  }

  public void readThenDoSomething(String id) {

    ModelDao model = dao.read(id);

    ...

  }

}

Class B {

  private IDao dao;

  public B(IDao dao) {

    this.dao = dao;

  }

  public void makeUpdate() {

    ModelDao model = new ModelDao();

    ...

    dao.update(model);

  }

  public void delete(String id) {

    dao.delete(id);

  }

}
    
posta jteezy14 20.02.2017 - 21:05
fonte

1 risposta

10

Il commento di Per Christopher, probabilmente è leggermente migliore per segregare le interfacce . Quindi avresti bisogno almeno di IReadDao , IDeleteDao e IUpdateDao . Nota che non hai necessariamente bisogno di tre classi; puoi avere una grande classe DAO che implementa tutte e tre le interfacce, se ha senso che il codice di base sia combinato in quel modo.

Per evitare l'esplosione combinatoria (ad esempio per evitare la necessità di un'interfaccia IReadUpdate , IDeleteUpdate , ecc.) è possibile fornire le interfacce separatamente nell'iniezione del costruttore (è possibile passare lo stesso oggetto due volte come parametri diversi), oppure fornire un singolo oggetto che supporta due o più interfacce in una chiamata al metodo generico utilizzando extends .

Iniezione del costruttore:

class MyDaoLibrary : IUpdateDao, IInsertDao, IDeleteDao {
    //Etc....
}

class A
{
    //It is OK if the IoC container factory provides the same instance for both parameters.
    a(IUpdateDao dao1, IDeleteDao dao2) {
        this.updater = dao1;
        this.deleter = dao2;
    }
    //Etc....
}

Iniezione settetta, utilizzando un metodo generico:

<T extends IUpdateDao & IDeleteDao> void InitializeDao(T dao)  //Pass a single object that implements both IUpdateDao and IDeleteDao
    
risposta data 20.02.2017 - 22:43
fonte

Leggi altre domande sui tag