Technorati Tags:

Parliamo di best practice con NHibernate e della tanto discussa relazione many-to-many. Per prima cosa bisogna fare due esempi, giusto per capire il succo del discorso. Nel primo caso vi illustro una relazione many-to-many classica che non potrebbe, e ribadisco, non potrebbe essere risolta diversamente per praticità e logica applicativa. L' esempio è il classico Utente/Gruppo.

image
In questo caso ho una classe Group che contiene dei gruppi di appartenenza e una classe User che le eguenti regole business :

  • Un utente puo' avere 1 o piu' gruppi
  • I gruppi non sono legati ad un utente particolare e non devono essere per forza associati ad un utente
  • Piu' utenti possono appartenere allo stesso gruppo

Ok ci verrebbe automatico pensare di creare le tre tabelle viste ieri, e gestire in questo modo la classica relazione molti-a-molti. Ma non va fatto!! Perchè?

Per prima vi riporto proprio una best practice del Domain Driven Design:

Don't use exotic association mappings.
Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.

Cosa significa? In questo caso se volessimo gestire le seguenti informazioni, adesso o in futuro, non saremmo in grado di farlo e dovremmo ridiscutere sia il Database, che il Dominio. Quello che ci richiedono è:

  • Tenere traccia storica delle aggiunte o rimozioni di gruppi
  • Inserire l' utente che ha autorizzato l' aggiunta o la rimozione di un certo gruppo

Per risolvere questo problema, la many-to-many non va bene perchè rende poco flessibile la soluzione e non modificabile e manutenibile ... La soluzione potrebbe essere questa:

image
In questo caso abbiamo una grafo diverso da prima, decisamente, ma adesso possiamo tracciare le modifiche ed usare la one-to-many e la many-to-one e rendere il grafo molto flessibile.

E' chiaro che questa è una possibile soluzione data dalle regole business imposte a priori, quindi siccome i gruppi non devono essere legati ad un utente, questa è la miglior soluzione. Intanto pero' ho uno stretto legame tra lo User e la classe intermedia.

Pro : ho reso il mio grafo piu' flessibile

Cons :  ho dovuto scrivere una classe in piu' ...