Oggetti immutabili e DDD vanno insieme?


18

Considera un sistema che utilizza DDD (anche: qualsiasi sistema che utilizza un ORM). Il punto di ogni sistema realisticamente, in quasi tutti i casi d'uso, sarà manipolare quegli oggetti di dominio. Altrimenti non ci sono effetti o scopi reali.

La modifica di un oggetto immutabile causerà la generazione di un nuovo record dopo la persistenza dell'oggetto che crea un enorme gonfiore nell'origine dati (a meno che non si eliminino i record precedenti dopo le modifiche).

Posso vedere il vantaggio dell'uso di oggetti immutabili, ma in questo senso non riesco mai a vedere un caso utile per l'uso di oggetti immutabili. È sbagliato?


Risposte:


16

Il calcolo usando oggetti immutabili (come nella programmazione funzionale) non implica necessariamente la persistenza di ogni oggetto generato!


Non vedo comunque un caso in cui quello scenario faccia comunque uso di oggetti immutabili, quindi sarebbero lì senza uno scopo particolare. Ho sbagliato?
Steven Evers,

1
stavo pensando che gli oggetti immutabili sarebbero stati utili per i calcoli intermedi (in thread paralleli)
Steven A. Lowe

11

Immutabile nel dominio significa che deve essere immutabile nel database? Ad esempio, si consideri il seguente presupposto che il cliente abbia sempre un indirizzo:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

ora viene eseguito il seguente sql considerando che l'ID cliente è 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

ora viene apportata la seguente modifica all'indirizzo:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

e il livello di persistenza, essendo molto intelligente esegue il seguente sql:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

In questo modo si evita il sovraccarico di un'istruzione DELETE AND INSERT separata. Inoltre penso che alcuni RDBMS abbiano INSERT REPLACE o qualcosa del genere. MySql ha REPLACE .


+1 Sono d'accordo con te sul principio generale: non vedo perché gli oggetti di dominio immutabili debbano necessariamente significare righe DB immutabili.
Andres F.

Nel caso precedente, se mai avessimo bisogno di cambiare l'attributo di città della classe di indirizzo per un determinato cliente come lo gestiremmo? Supponiamo inoltre che il cliente possa avere più indirizzi in modo da avere una relazione tra una e più navi tra cliente e indirizzi
Sudarshan

1
@Sudarshan questo è solo un modo per creare un 'oggetto valore immutabile', non proprio immutabile nel database. Per motivi di prestazioni. Ogni situazione deve essere gestita in modo specifico ofcourse. Ora preferisco il sourcing di eventi per il mio dominio, ma sono un po 'dipendente da esso.
andho,

@Sudarshan per rispondere in modo specifico alla tua domanda, devi solo eseguire una query di aggiornamento che aggiorna la riga al nuovo valore. Se è uno-a-molti, gli indirizzi avranno un qualche tipo di identificativo all'interno della radice aggregata del cliente che verrà utilizzato per identificarlo in modo univoco nel DB. Quindi questo identificatore e customer_id verranno utilizzati per aggiornare quella riga nella tabella "address".
andho,

@andho "questo è solo un modo per creare un" oggetto valore immutabile ", non proprio immutabile nel database." questo mi ha davvero reso grazie
Sudarshan,

6

In DDD, gli oggetti immutabili si equivalgono praticamente agli oggetti valore. Questi oggetti non sono entità, non hanno un'identità. Pertanto persisto sempre oggetti valore come colonne dell'entità in cui sono contenuti (con N / Hibernate è possibile utilizzare i componenti per questo). Non hanno un tavolo tutto loro.


4

Dipende da come l'oggetto immutabile è mappato nel database. Se è solo un componente come un DateTime (dalla libreria Joda Time), la modifica del valore comporterà un aggiornamento anziché un inserimento. Tuttavia, se l'immutabile è più complesso e richiede una riga in una tabella, allora hai il problema di gonfiaggio.

Suppongo che, sebbene si tratti di un argomento debole, potresti implementare una pista di controllo in questo modo. Ogni modifica all'immutabile può essere tracciata attraverso gli inserti. Esistono molti modi migliori per farlo.

Tutto sommato avere oggetti di dominio immutabili (invece che semplicemente i loro componenti) sembra un po 'incompatibile con la persistenza.


Affatto. I componenti sono molto utili poiché consentono agli oggetti di dominio di essere composti in modo diverso dagli stessi dati sottostanti. I problemi derivano dal far rispettare l'immutabilità. Personalmente, tratterei gli oggetti di dominio come mutabili (ad eccezione dei campi chiave primaria) e lo renderei semplice.
Gary Rowe,

"Tutto sommato avere oggetti di dominio immutabili (invece che semplicemente i loro componenti) sembra un po 'incompatibile con la persistenza." Secondo te dove dovremmo avere oggetti valore che non dovrebbero essere modellati come componenti (terminologia di ibernazione)? --- Mi dispiace di aver sbagliato a scrivere il mio ultimo commento e quindi l'ho eliminato.
Sudarshan,

Evita i componenti quando una singola entità è rappresentata completamente da una riga e nessuno dei dati è condiviso da un altro oggetto di dominio.
Gary Rowe,

4

Dipende dal dominio. DDD non specifica che il paradigma di programmazione è orientato agli oggetti. Il paradigma orientato agli oggetti è tuttavia adatto per l'applicazione tipica che deve essere mantenuta in un database.

DDD afferma semplicemente che dovresti costruire il tuo software attorno a un modello di dominio che rappresenti il ​​problema reale che il software sta cercando di risolvere. Se quel problema fosse per esempio matematico, l'implementazione del livello di dominio usando la programmazione funzionale e le strutture di dati immutabili avrebbe molto senso.

Se d'altra parte, il problema è più di una tipica applicazione aziendale e stai usando strutture di oggetti immutabili per tutti i tuoi oggetti di dominio, direi che non stai seguendo DDD. Posso venire con almeno due argomenti:

  • L'implementazione non rappresenta un modello di dominio del dominio problematico. Il tuo dominio problematico in questo caso è costituito da entità che hanno lo stato da modificare. E non è così che lo hai implementato.

  • Non hai un linguaggio onnipresente. La lingua e i concetti nel modello di dominio non seguono ciò che usano gli esperti del dominio.

Nota: DDD utilizza oggetti immutabili dove appropriato, sono semplicemente chiamati oggetti valore.

Quindi non sto dicendo che non è possibile creare un'applicazione di database utilizzando strutture di dati puramente funzionali e non sto dicendo che non dovresti. Non penso che tu possa chiamarlo DDD, a seconda del tipo di applicazione


Peter, ottima risposta. Potresti dare un'occhiata alla mia domanda qui stackoverflow.com/questions/13783666/… e aiutarmi a capire il mio problema. Penso che gli oggetti di valore immutabile siano fantastici per i software che non sono correlati all'azienda. A mio avviso, la maggior parte degli oggetti delle applicazioni aziendali è mutevole. Immagina di avere un oggetto valore annidato in profondità immutabile ... ContactInfo-> PhysicalLocation-> Indirizzo e vuoi aggiornare il codice postale ... la creazione dell'intero grafico oggetto mi sembra anticristo, non solo un antipattern. cosa pensi?
Pepito Fernandez,

3

Se si utilizza un ORM come Hibernate / NHibernate, è possibile impostare l'opzione a cascata per eliminare automaticamente gli oggetti orfani. Se una persona ha un oggetto valore Indirizzo, quando si modifica l'indirizzo, quello nuovo verrà salvato e quello vecchio eliminato perché ora è orfano.


0

Gli oggetti valore sono quasi sempre immutabili in DDD e il modello flyweight può essere utilizzato per mantenere in memoria la duplicazione di tale oggetto valore proprio come fa .NET con le stringhe. Il principale compromesso è la memoria da un lato e l'altro lato è l'efficienza della creazione. Con il modello flyweight, è necessario eseguire un confronto basato sul valore per determinare se un oggetto valore nuovo o ricostituito è già all'interno della cache del peso mosca, ma qualsiasi altro confronto successivo a quel punto può essere generalmente eseguito in modo sicuro come riferimento poiché viene applicata una singola istanza. In ogni caso, sia che si utilizzi o meno il peso mosca, gli oggetti valore sono ancora resi immutabili perché hanno solo un'identità intrinseca e quindi cambiando il loro valore cambierebbe la loro identità.


-1

C'è un altro modo di usare oggetti immutabili ...

Invece di memorizzare i valori 5.0, 6.0, 7.0, 8.0 e copiare l'intero record ogni volta, puoi invece archiviare qualcosa del genere: 5.0, +1.0, +1.0, +1.0 e quindi creare correttamente le dipendenze per ricostruire la sequenza 5.0 , 6.0, 7.0, 8.0. In questo modo piccole modifiche richiedono solo una piccola quantità di memoria ...

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.