Eredità e fabbrica insieme?

4

Ho un modello di dati gerarchico e sto cercando di implementare le loro operazioni CRUD nella mia applicazione Web.

Attualmente ho ereditarietà di codice per le operazioni CRUD delle mie entità (risorse) come segue:

ResourceCommonProcedures come classe base e ogni procedura risorsa eredita la classe base.

public class ResourceCommonProcedures { 

    public Response create(Request request){
        Response response = new Response();
        int resType = this.getResourceType(request);

        ResourceCommonProcedures rp = getResourceController(resType);
        response = rp.create(request);

        return response;
    }

private ResourceCommonProcedures getResourceController(int resourceType){
            //..

            switch(resourceTypeName){


            case Resource1:
                return new R1Procedures();

            case Resource2:
                return new R2Procedures();

            case Resource3:
                return new R3Procedures();
            ............... 

}
}

Class R1Procedures extends ResourceCommonProcedures{


public Response create(Request request) {

        Response response = new Response();
            Resource1 resource = (Resource1) request.getContent();

            ...........
            // Converts DB structure to JPA 
            R1Converter r1Converter = new R1Converter();
            Resource1JPA resourceJpa = r1Converter.toJPA(resource);
            dao.persist();

            return response;

}
}

Class R2Procedures extends ResourceCommonProcedures{


public Response create(Request request) {

        Response response = new Response();
            Resource1 resource = (Resource2) request.getContent();

            // SOME RESOURCE 2 SPECIFIC CODE
            ...........
            // Converts DB structure to JPA 
            R2Converter r2Converter = new R2Converter();
            Resource2JPA resourceJpa = r2Converter.toJPA(resource);
            dao.persist();

            return response;


}

Quindi attualmente la base ha il codice del controller che decide quale metodo di sottocategoria deve essere chiamato.

Quindi il client chiamerà il metodo di creazione della classe base, che otterrà internamente la classe di implementazione e chiamerà il metodo di creazione specifico.

Questo design è abbastanza buono ??

O il getResourceController() deve essere estratto dalla classe base e inserito in una classe separata ??

Esiste un modello di design specifico per il caso ??

    
posta Siddharth Trikha 07.03.2017 - 10:39
fonte

2 risposte

2

Vorrei andare per una classe generica astratta:

public class AbstractProcedure<T extends BusinessObject, TJPA extends JPAObject, TConverter extends Converter<T, TJPA >>{

public abstract TConverter<T, TJPA> getConverter();

public Response create(Request request) {
    Response response = new Response();
        T resource = (T) request.getContent();

        ...........
        // Converts DB structure to JPA 
        R1Converter r1Converter = getConverter();
        TJPA resourceJpa = r1Converter.toJPA(resource);
        dao.persist(resourceJpa);
        return response;
    }
 }

public class R1Converter implements Converter<R1, R1JPA>{
         @Override // come from the Converter interface
         public R1JPA toJpa(R1 object){}
}
public class R1Procedure extends AbstractProcedure<R1, R1JPA, R1Converter>{
      R1Converter converter = new R1Converter();
      public R1Converter getConverter(){
           return converter;
      }
}

Alcuni punti da considerare:

  • Potresti voler rinominare il tuo "Convertitore" in "Scheda"
  • Gestire la richiesta del database nella stessa classe piuttosto che ottenere i dati dalla richiesta viene in genere suddiviso in classi separate per la separazione dei problemi. Cosa succede se domani un gruppo deve creare entità?
  • È possibile sovrascrivere la funzione di creazione per aggiungere un valore predefinito, controllare correttamente e chiamare super.create (). Sebbene l'uso di super non sia raccomandato, questo è un uso sensato di IMHO.
risposta data 07.03.2017 - 11:49
fonte
1

Questo è un progetto un po 'strano. Il punto di ereditare è che non devi avere questi grandi blocchi se.

Se si rende il comune getResourceController virtuale, è possibile sovrascriverlo nelle classi figlie e implementare la logica specifica della classe lì. salvandoti l'interruttore.

es. getResourceController(int resourceType) è ereditato (e chiamato da?) R1Procedures . resourceType è memorizzato nell'istanza della classe

int resType = this.getResourceType(request);

quindi dovresti già avere un processo R1 istanziato che dovrà solo chiamare il proprio ramo della logica getResourceController .

Ma probabilmente puoi farlo ulteriormente e rimuovere del tutto la classe di basso. Il tuo codice di esempio non ha una funzionalità comune.

Ciò che manca dal tuo esempio di codice è l'input iniziale che richiede di creare una classe di tipo X. È questo punto di ingresso che è il fattore chiave nel determinare come istanziati i vari oggetti che utilizzerai nella tua logica.

    
risposta data 07.03.2017 - 10:50
fonte