Passare oggetti di valore elevato o convertirli in oggetti di valore inferiore

6

Diciamo che ho un progetto che deve fare quanto segue:

  • Chiamate multiple da leggere dal database in cui ogni chiamata è una query diversa e restituisce un oggetto valore (ha solo getter / setter). Diciamo che finiamo di ricevere 20 oggetti valore
  • Esegue un po 'di logica con i dati di questi oggetti valore

Sto cercando di fare il brainstorming della best practice per i parametri ai miei metodi per il secondo punto, dato che alcuni oggetti valore potrebbero avere più campi di quelli richiesti dai miei metodi.

Diciamo che voglio realizzare il secondo punto elenco avendo molte classi che eseguono ciascuna una parte del lavoro. Supponiamo che una classe abbia bisogno di 7 campi da un oggetto valore e 8 campi da un altro oggetto valore e che entrambi gli oggetti valore abbiano ciascuno più di 30 campi. Posso pensare a 3 modi per farlo:

  1. Chiedi alla mia classe di prendere in considerazione i due oggetti valore di cui ha bisogno come parametro. La classe chiamerà quindi 15 getter e poi farà qualcosa con i campi. Prendi questo stesso approccio per il resto delle mie classi dove prendono gli oggetti valore di cui hanno bisogno

  2. Codifica un nuovo oggetto valore che memorizza solo i 15 valori di cui ho bisogno. Da qualche parte nella mia applicazione dovrò fare una mappatura / conversione da questi due oggetti valore al mio nuovo oggetto valore. La mia classe chiamerà 15 getters e poi farà qualcosa con i campi. Prendi questo stesso approccio per il resto delle mie classi

  3. Codifica qualche oggetto di valore enorme che memorizza tutti i dati di cui ho bisogno per l'intero secondo punto elenco. Prendiamo fondamentalmente tutti i nostri oggetti di valore e convertiamo tutti i dati di cui abbiamo bisogno in questo enorme oggetto di valore. La mia classe prenderà allora questo enorme oggetto di valore. La mia classe chiamerà 15 getters e poi farà qualcosa con i campi. Ogni classe che fa una parte della logica prenderà in questo enorme oggetto valore

Qual è l'approccio migliore?

  1. sembra l'approccio più semplice. Tuttavia, è strano avere una classe che richiede più informazioni del necessario. Qualcuno che guarda la classe potrebbe voler sapere perché richiede 60 campi se ne userà solo 15.

  2. sembra di gran lunga il più complicato in quanto ha molti mapping diversi ma ogni singola classe finisce per chiedere solo ciò di cui ha bisogno.

posta radian 09.09.2018 - 06:36
fonte

4 risposte

5

La ricerca dell'approccio migliore è sempre problematica nell'ingegneria del software, perché di solito non esiste un unico approccio migliore. Ogni approccio ha dei compromessi che lo rendono migliore o peggiore in alcune situazioni.

Una cosa che dovrebbe essere in cima alla lista di cosa ottimizzare è la leggibilità e la manutenibilità, in modo che le persone che non hanno visto il codice prima o che non lo vedono da un po 'di tempo possono facilmente capire cosa sta facendo il codice .

Un aspetto della leggibilità è di avere classi che rappresentano un concetto coerente. Gli oggetti valore non sono un insieme di proprietà che vengono messe insieme in un contenitore. Gli oggetti valore dovrebbero, proprio come entità, rappresentare un concetto coerente. Ad esempio, un indirizzo ha diverse proprietà, come il nome della via, la città, il codice postale, ecc., Ma non si dovrebbe creare un oggetto valore che consiste nelle proprietà per un indirizzo e il colore della casa, solo perché è conveniente per alcune funzioni. Molto probabilmente, quella raccolta di proprietà rappresenta più concetti e dovrebbe essere suddivisa in oggetti con più valori.

Questo ci porta alla risposta alla tua domanda.
Se gli oggetti valore corrente che hai per l'opzione 1 rappresentano ciascuno un concetto unico, coerente, allora l'opzione 1 è sicuramente l'opzione da scegliere. È molto naturale che non tutte le funzioni abbiano bisogno di tutte le proprietà di un oggetto valore (specialmente se è piuttosto grande con molte proprietà), ma questo non è un problema. Vedere solo una parte di un concetto ben compreso è di solito più facile da capire che vedere un'operazione su un sacco casuale di proprietà.

Se gli oggetti valore corrente non rappresentano concetti coerenti singoli, allora offrirei l'opzione 4: creare nuovi oggetti valore che rappresentino ciascuno un unico concetto coerente e basino le operazioni su di essi.

    
risposta data 09.09.2018 - 08:49
fonte
6

1) Have my class take in the two value objects it needs as a parameter. The class will then call 15 getters and then do something with the fields. Take this same approach for the rest of my classes where they take in the value objects they need

Questo è l'approccio al dominio anemico. Funziona bene se non cambi mai DB, tabelle o campi o non ti importa quando tali cambiamenti rompono molte cose in molti posti. Ciò significa che la tua applicazione ha familiarità con i dettagli del DB.

2) Code up a new value object which only stores the 15 values that I need. Somewhere in my application I will have to do a mapping/conversion from these two value objects to my new value object. My class will call 15 getters and then do something with the fields. Take this same approach for the rest of my classes

Si sta applicando il refactoring introduce oggetto parametro . Non si limitano a spostare tutti i parametri di alcuni metodi in un oggetto parametro. Si interrompe e si raggruppano i parametri dei metodi in modo che si finisca con un numero inferiore di argomenti che contengono gruppi concettualmente coerenti. Questi piccoli oggetti per il trasferimento dei dati possono concentrarsi su parte delle esigenze dei metodi. Potrebbero anche essere riutilizzabili.

Ad esempio, non rifattorici:

void draw(int x, int y, int r, int g, int b)

in questo:

void draw(DrawArgs drawArgs)

Rifattalo in questo:

void draw(Point point, Color color)

Fatelo anche se il DB ha solo i dati e non ha idea di quali siano i punti e i colori.

3) Code up some huge value object that stores all of the data that I need for the entire second bullet point. We basically take all of our value objects and convert all the data we need to this huge value object. My class will then take in this huge value object. My class will call 15 getters and then do something with the fields. Each class that does a portion of the logic will take in this huge value object

Questo è chiamato oggetto God . È quello che succede quando smetti di organizzarti e butti tutto in un posto solo. Nasconde semplicemente il casino da qualche altra parte.

    
risposta data 09.09.2018 - 18:53
fonte
3

Hai un'elaborazione molto complessa che prende come valore oggetti di valore appartenenti a 20 classi diverse. Supponiamo che siano oggetti ben definiti e coerenti del dominio dell'applicazione.

Il tuo progetto suddivide la complessa elaborazione degli oggetti del dominio in attività più piccole che sono incapsulate in classi più piccole e più facili da gestire.

L'opzione 1 sembra qui la scelta più appropriata : tu prendi come input degli oggetti di dominio coerenti ben definiti e hai solo bisogno di una parte di essi. Ciò ha notevoli vantaggi:

  • Un giorno potresti scoprire un modo migliore per eseguire l'attività elementare utilizzando una proprietà aggiuntiva dell'oggetto dominio: puoi apportare miglioramenti senza cambiare l'interfaccia "naturale" basata sugli oggetti del dominio.
  • Un giorno un oggetto dominio potrebbe evolvere e contenere più campi da considerare: nessuna preoccupazione, nessuna necessità di cambiare le interfacce delle tue attività.

Tutte le altre scelte sono meno ottimali:

  • Opzione 2: crei un nuovo oggetto intermedio, con la speranza di ottenere una migliore segregazione dell'interfaccia in modo che la classe dipenda solo da ciò di cui ha bisogno. Ma in realtà, hai creato una nuova interfaccia arbitraria, che non rappresenta una realtà di dominio e alla fine dipende ancora indirettamente dalle classi di dominio!
  • Opzione 3: il tuo oggetto enorme semplifica il passaggio dei parametri all'estremo. Ma a quale costo? Perderai la maggior parte dei vantaggi dell'incapsulamento in attività più piccole. Avrai difficoltà a mantenere una panoramica su quali classi modifica / aggiorna / genera cosa.
risposta data 09.09.2018 - 16:31
fonte
0

Hmmmm ... Quindi hai più oggetti valore (forse 20 o più in base al tuo post) che hanno più relazioni tra loro e devono essere orchestrati.

Questo suona molto simile a un paio di modelli di integrazione aziendale (EIP) che compongono il tuo processo end-to-end. Mi sembra che il tuo processo debba compiere le seguenti operazioni:

  • Message / Data Aggregation: raccoglie tutti i dati richiesti da tutti gli oggetti valore richiesti
  • Sequenza messaggi: organizza gli oggetti valore in entrata nella sequenza corretta
  • Arricchimento del contenuto: aggiungi / aggiusta il carico utile degli oggetti valore in base all'input

Penso che lo strumento migliore per ciò che vuoi realizzare sia un "modello di costruttore" con orchestrazione, assemblaggio e arricchimento dei tuoi VO. Vorrei usare Apache Camel per quello che vuoi fare.

Apache Camel

    
risposta data 09.09.2018 - 18:25
fonte