Come modellare un tipo di indirizzo in DDD?

6

Ho un'entità User che ha un Set di Address dove Address è un oggetto valore:

class User{
    ...
    private Set<Address> addresses;
    ...
    public setAddresses(Set<Address> addresses){
        //set all addresses as a batch
    }
    ...
}

Un User può avere un home address e un work address , quindi dovrei avere qualcosa che funge da ricerca nel database:

tbl_address_type

------------------------------------------------
|    address_type_id       | address_type      |
------------------------------------------------
|            1             |      work         |
------------------------------------------------
|            2             |      home         |
------------------------------------------------

e corrispondentemente tbl_address

-------------------------------------------------------------------------------------
|    address_id       |     address_description      |address_type_id|    user_id   |
-------------------------------------------------------------------------------------
|          1          |      123 main street         |      1        |      100     |
-------------------------------------------------------------------------------------
|          2          |      456 another street      |      1        |      100     |
-------------------------------------------------------------------------------------
|          3          |      789 long street         |      2        |      200     |
-------------------------------------------------------------------------------------
|          4          |      023 short street        |      2        |     200      |
-------------------------------------------------------------------------------------
  1. Il tipo di indirizzo dovrebbe essere modellato come tipo Entità o Valore? e perché?
  2. Va bene per l'oggetto Valore Address mantenere un riferimento all'Entità AdressType (nel caso in cui sia stato modellato come entità)? È qualcosa fattibile usando Hibernate / NHibernate?
  3. Se un utente può modificare il suo indirizzo di casa, dovrei esporre una funzione User.updateHomeAddress(Address homeAddress) sull'entità User stessa? Come posso far rispettare il fatto che il cliente passa un indirizzo di casa e non un indirizzo di lavoro in questo caso? (Un'implementazione esemplificativa è molto gradita)
  4. Se voglio ottenere l'indirizzo di casa dell'utente tramite la funzione User.getHomeAddress() , devo caricare l'intero array di indirizzi, quindi eseguirne il ciclo e controllare ciascuno per il suo tipo finché non trovo il tipo corretto e poi lo restituisco? Esiste un modo più efficiente di questo?
posta Songo 10.11.2013 - 23:49
fonte

5 risposte

5

Penso che il tipo non sia una proprietà dell'indirizzo, è una proprietà della connessione tra un utente e un indirizzo.

Un indirizzo normalmente rappresenta una posizione specifica nel mondo, un tipo sarebbe connesso all'uso che un utente fa dell'indirizzo.

Un indirizzo potrebbe anche essere usato sia da casa che da lavoro per alcuni utenti. O essere la casa di un utente e il luogo di lavoro di un altro utente.

  1. L'indirizzo deve essere un tipo di valore.
  2. Non dovrebbe essere connesso a AddressType
  3. Per me dipenderebbe dal numero di indirizzi che ci si aspetta che l'utente abbia, e da quanto statico sarà il tipo.
  4. Una specie di mappa sarebbe più efficiente ...
risposta data 13.11.2013 - 12:14
fonte
2

La domanda che vorrei porre a me stesso, dal punto di vista del DDD, è "l'indirizzo sa che è una casa o un'azienda o cosa hai?"

La risposta è probabile no. Un modello leggermente migliore sarebbe avere un utente che ha una collezione di indirizzi come quella che stai visualizzando, ma anche aggiungere una proprietà che punta agli indirizzi home / business / primari come richiesto.

Una nota tecnica è che, ai fini della consegna del pacchetto, dovresti avere un flag "Is Residential" sull'indirizzo, oltre a un flag "Is PO Box" per filtrare quelli fuori mentre cambiano materialmente il modo in cui uno può consegnare le cose quali sono i tipi di cose che un oggetto indirizzo dovrebbe capire.

    
risposta data 12.11.2013 - 20:08
fonte
2

L'utente ha bisogno di più di 3 indirizzi? Raramente. Raccomando di denormalizzare la raccolta di indirizzi.

L'utente avrà semplicemente i campi address_home , address_work , address_other dove tutti e 3 saranno di tipo Address , che sarà il tipo di valore.

Questo modello copre il 99,99% dei casi d'uso, è molto più facile da capire, è facilmente implementabile nel codice e si adatta molto meglio sia al modello relazionale che a quello del documento.

E se prevedi di utilizzare DB relazionale, puoi avere tutti i dati in User table, il che velocizzerà notevolmente il recupero.

Se la denormalizzazione non è un'opzione , modellerei gli indirizzi come Map / Dictionary con indirizzo come valore e stringa o qualche tipo di enum come chiave. Il Address sarebbe un oggetto valore immutabile e il modello relazionale sarà una singola tabella con chiave primaria composta da userId e la chiave della mappa. Pertanto, l'indirizzo stesso non avrebbe un identificatore. Il resto del tavolo sarebbero dati dell'indirizzo. Ciò mantiene il modello semplice e facile da capire. Ma la mappatura tra dizionario e tabella relazionale potrebbe non essere così semplice. Ma è ancora fattibile.

    
risposta data 12.11.2013 - 21:06
fonte
1

Quello che sembra che manchi a tutti è che un singolo indirizzo può essere utilizzato da diversi utenti.

Quindi ti serve qualcosa come:

User  Usage Addr
   1      1    1
   1      2    2
   2      1    3
   2      2    2
   3      1    1

Id  Number     Street        Town
1   23         Accai Drive   Hoboken
2   15         Wall Street   N.Y.C
3   99         First Street  Armonk       

In questo modo puoi condividere le posizioni degli uffici tra college e indirizzi di casa tra i conviventi. Risolve anche il problema di ciò che inserisci nell'indirizzo di "lavoro" per le persone che lavorano da casa.

    
risposta data 18.11.2013 - 08:37
fonte
0

Should the address type be modeled as an Entity or Value type? and Why?

Penso che l'indirizzo sia un candidato per un modello di dominio. È normale che gli oggetti indirizzo abbiano un comportamento di convalida. Ad esempio, è possibile controllare che determinati campi siano impostati o che il codice postale sia valido prima di impostarlo. Alcuni potrebbero sostenere che la convalida del codice postale non dovrebbe essere eseguita nell'oggetto indirizzo. Questo può essere discusso.

Is it OK for the Address Value object to hold a reference to the Entity AdressType (in case it was modeled as an entity)? Is this something feasible using Hibernate/NHibernate?

Suppongo che AddressType sia definito nel tuo livello di accesso ai dati. Se questo è il caso, allora a un certo punto vorrai esporre il tuo indirizzo nei livelli di presentazione o di servizio. All'improvviso la logica del livello dati sta perdendo nei livelli di presentazione e di servizio.

If a user can change his home address, should I expose a User.updateHomeAddress(Address homeAddress) function on the User entity itself? How can I enforce that the client passes a Home address and not a work address in this case? (a sample implementation is most welcomed)

Non penso che User.updateHomeAddress(Address homeAddress) sia una buona strada da seguire. Suppongo che nel tuo sistema l'utente abbia un ruolo importante. Non vorrei accumulare preoccupazioni relative all'utente in una singola classe User . Più responsabilità darai all'utente, più difficile diventerà il tuo codice.

Una delle soluzioni è avere una classe di comando per l'aggiornamento dell'indirizzo.

es.

public class UpdateHomeAddressCommand 
{
   private User _user;
   private Address _address;

   public UpdateHomeAddressCommand(User user, Address address)
   {
      _user = user;
      _address = address;
   }       

   public void Execute()
   {
       // Update logic
   }
}

Nell'esempio sopra, sto usando un semplice comando per aggiornare l'indirizzo. Se trovi che la logica per aggiornare l'indirizzo di casa e di lavoro è molto simile, allora puoi spostarla in una classe astratta e quindi rendere UpdateHomeAddressCommand ereditare dall'abstract UpdateAddressCommand .

If I want to get the User's home address via User.getHomeAddress() function, must I load the whole addresses array then loop it and check each for its type till I find the correct type then return it? Is there a more efficient way than this?

Idealmente il tuo livello dati dovrebbe restituire solo i dati di cui hai bisogno. Altrimenti, i dati non necessari viaggiano sul filo.

    
risposta data 18.11.2013 - 09:42
fonte

Leggi altre domande sui tag