Entità all'utilizzo DTO


15

Ho cercato di trovare un flusso per un'applicazione Web a livelli di base e ho letto informazioni contrastanti online. Quello che sto cercando di capire è se c'è un vantaggio nell'usare ancora oggetti DTO dal livello DAO al servizio attraverso l'uso di una sorta di mapper.

Il flusso di base che prevedo è il seguente:

  1. Modello / modulo interfaccia utente -> Controller
  2. Il controller converte il modello in oggetto di dominio (entità)
  3. Oggetto di dominio -> Livello di servizio
  4. Oggetto di dominio -> DAO
  5. DAO -> Oggetti dominio
  6. Servizio -> UI
  7. L'interfaccia utente converte il dominio in modelli dell'interfaccia utente

Se fosse seguito DTO, DAO avrebbe restituito un DTO non l'Entità. Dopo aver letto un po 'sembra che DTO sia diventato leggermente defunto poiché (almeno in Java) le entità sono diventate POJO annotate, il che significa che la loro impronta di memoria è diventata molto piccola.

È questo il caso o dovrebbero essere utilizzati DTO per incapsulare completamente gli oggetti di dominio all'interno del livello DAO e, in tal caso, quale livello di servizio passerebbe al DAO?

Grazie mille!

Risposte:


20

Secondo me, passare un POJO persistente, come ad esempio un bean gestito da JPA, non è LA buona prassi.

Perché?

Vedo tre motivi principali:

  1. Potenziale problema con raccolte pigre. http://java.dzone.com/articles/avoid-lazy-jpa-collections
  2. L'entità dovrebbe contenere un comportamento (al contrario di un modello di dominio Anemic ) Potresti non voler lasciare che la tua UI chiami un comportamento inaspettato.
  3. Nel caso di un modello di dominio anemico potresti non voler esporre la struttura del modello all'interfaccia utente, poiché ogni nuova modifica al modello potrebbe interrompere l'interfaccia utente.

Preferisco consentire al mio livello di servizio di convertire entità in DTO corrispondente in entrambe le direzioni. DAO restituisce ancora entità (non è suo compito garantire la conversione).


Quindi, se lo capisco correttamente, il servizio si occupa essenzialmente solo di oggetti DTO e funge da intermediario dell'interfaccia utente e di DAO. Inoltre, al punto 3, è ancora necessario convertire il DTO in elementi dell'interfaccia utente realizzabili, quindi un aggiornamento del dominio non interromperebbe comunque l'interfaccia utente a causa del fatto che DTO necessitava anche di un aggiornamento.
dardo,

1
Gli elementi dell'interfaccia utente @dardo SONO DTO o, nel peggiore dei casi, devono essere convertiti in DTO prima di chiamare alcuni servizi sul lato server. È probabile che il DTO non cambi spesso, ci sono solo adattamenti delle tue entità incentrati sulle esigenze dell'interfaccia utente. Inoltre, il livello di servizio dovrebbe interessare sia: DTO che entità.
Mik378,

Ah ok, c'è il singhiozzo che non capivo. Il modello di dominio anemico è piuttosto comune dove lavoro, e sto cercando di spostare un po 'il paradigma per incoraggiare un livello di servizio più sottile. Grazie ancora!
dardo,

@dardo Puoi leggere questo libro. (o
mostralo

effettivamente ottenuto questo su kindle, amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/… abbastanza bene finora = D
dardo

13

Uno dei motivi per cui penso che questa discussione si ripeta ripetutamente è perché sembra un vero problema prendere un oggetto con tutti i dati necessari e convertirlo in un oggetto che sembra identico o quasi identico a quello stai cedendo.

È vero, è una PITA. Ma ci sono alcuni motivi (oltre a quelli elencati sopra) per farlo.

  • Gli oggetti di dominio possono diventare molto pesanti e contenere molte informazioni inutili per la chiamata. Questo gonfiamento rallenta l'interfaccia utente a causa di tutti i dati trasmessi, sottoposti a marshalling / senza marshalling e analizzati. Se consideri che una FE avrà numerosi link che si riferiscono ai tuoi servizi web e che ti vengono chiamati con AJAX o qualche altro approccio multi-thread, renderai rapidamente lenta la tua interfaccia utente. Tutto ciò arriva alla scalabilità generale dei servizi web
  • La sicurezza può essere facilmente compromessa esponendo troppi dati. Come minimo, puoi esporre gli indirizzi e-mail e i numeri di telefono degli utenti se non li elimini dal risultato DTO.
  • Considerazioni pratiche: per 1 oggetto da sfilare come un oggetto di dominio persistente E un DTO dovrebbe avere più annotazioni del codice. Avrai un numero qualsiasi di problemi con la gestione dello stato dell'oggetto mentre passa attraverso i livelli. In generale, questo è molto più di un PITA da gestire, quindi semplicemente fare il tedio di copiare i campi da un oggetto di dominio a un DTO.

Tuttavia, puoi gestirlo in modo abbastanza efficace se incapsuli la logica di traduzione in una raccolta di classi di convertitori

Dai un'occhiata a lambdaJ dove puoi fare 'convert (domainObj, toDto)' c'è un sovraccarico di questo per l'uso con le raccolte. Ecco un esempio di un metodo controller che lo utilizza. Come puoi vedere, non sembra così male.

    @GET
    @Path("/{id}/surveys")
    public RestaurantSurveys getSurveys(@PathParam("id") Restaurant restaurant, @QueryParam("from") DateTime from, @QueryParam("to") DateTime to) {

        checkDateRange(from, to);

        MultiValueMap<Survey, SurveySchedule> surveysToSchedules = getSurveyScheduling(restaurant, from, to);
        Collection<RestaurantSurveyDto> surveyDtos = convert(surveysToSchedules.entrySet(), SurveyToRestaurantSurveyDto.getInstance());
        return new RestaurantSurveys(restaurant.getId(), from, to, surveyDtos);

    }

Grazie per l'input, e il mio pensiero è sulla stessa linea =)
dardo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.