La mia sensazione su questo è che gli oggetti dominio (non dominio entità, poiché tale titolo implica qualcosa a che fare con un database) non devono essere interfacce a meno che non si abbia una ragione molto convincente per credere che sarà necessario supportare più implementazioni ad un certo punto nel futuro.
Si consideri che il modello di dominio è il modello umano. Il business/servizio/documento è, letteralmente, il dominio. Molti di noi stanno sviluppando software per una singola azienda o scopo. Se il modello di dominio cambia, è perché le regole di business sono cambiate, e quindi il vecchio modello di dominio non è più valido - non c'è motivo di mantenere quello vecchio in giro, correndo accanto a quello nuovo.
Il dibattito non è ovviamente in bianco e nero. Potresti sviluppare software pesantemente personalizzato su più siti client. Potrebbe essere necessario implementare contemporaneamente diversi set di regole aziendali e contemporaneamente avere una reale necessità di adattarle a un'architettura unificata. Ma, almeno nella mia esperienza, questi casi sono l'eccezione piuttosto che la regola, e anche se generalmente non mi piace molto il termine, questo potrebbe essere il caso in cui dovresti pensare a te stesso, YAGNI.
L'accesso ai dati è un'area comune in cui si desiderano astrazioni migliori (persistence ignorance). Nel tuo esempio, hai gli attributi di NHibernate sulla tua classe del modello. Ma aggiungere gli attributi di persistenza non rende più una vera classe di dominio perché introduce una dipendenza su NHibernate. NHibernate e Fluent NHibernate supportano la mappatura dei POCO utilizzando una dichiarazione di mappatura esterna invece degli attributi sulla classe di dati e questo tende ad essere l'approccio preferito quando si utilizzano ORM come NHibernate o EF4, perché interrompe la dipendenza tra modello di persistenza e modello di dominio.
Se questi metodi di mappatura non sono stati supportati, e si avuto utilizzare gli attributi, allora potrei davvero suggerire utilizzando interfacce, invece, ma ORM oggi sono più sofisticati di quello, con la riflessione e proxy dinamici e il metodo di intercettazione a che fare la maggior parte del sollevamento pesante, quindi non è necessario creare le proprie astrazioni qui.
Alcuni tipi di oggetti che si desidera desidera esporre come interfacce sono:
- Repository, che sono responsabili per il caricamento/salvataggio oggetti di dominio;
- Plugin/estensioni del programma;
- Modelli di View/Presenter, in modo che possano essere inserite diverse UI;
- Tipi di dati astratti con molte implementazioni (matrice, elenco, dizionario, set di record e tabella dati sono tutte sequenze AKA
IEnumerable
);
- Operazioni astratte con molti algoritmi possibili (ordinamento, ricerca, confronto);
- Modelli di comunicazione (stesse operazioni su TCP/IP, named pipe, RS-232);
- Qualsiasi specifica della piattaforma, se si prevede di eseguire l'implementazione su più di una (Mac/Windows/* nix).
Questo è in alcun modo un elenco completo, ma dovrebbe illuminare il principio di base qui, cioè che le cose più adatto di interfacciarsi astrazioni sono le cose che:
- dipendono da fattori che possono al di là del tuo controllo;
- È probabile che cambi in futuro; e
- Sono funzioni orizzontali (utilizzate in molte parti dell'app/architettura).
Una classe di dominio sarà ampiamente utilizzata, ma non si adatta a nessuna delle prime due categorie; non è probabile che cambi, e hai quasi il controllo completo sul design. Pertanto, a meno che le classi stesse non assumano dipendenze indirette (che è una situazione che dovresti cercare di evitare quando possibile), non passerei attraverso lo sforzo extra di creare un'interfaccia per ogni classe nel modello di dominio.
@Aaronaught: Ok per ORM specifico, ora presumo che io stia usando le funzionalità FullText, userò Lucene.NET che usa anche gli Attributi. E per quanto ne so, non c'è modo di usare la mappatura degli attributi esterni come fa FluentNhibernate. Quindi qual è l'approccio migliore per mantenere le mie entità di dominio autentiche POCO? Forse le interfacce funzionano in questo modo? –
@Yoann. B: Non ero a conoscenza del fatto che Lucene.NET usasse gli attributi di decoratore; sicuramente non li richiede. Se vuoi usarli, hai due possibilità: o (a) rendere il tuo modello di dominio dipendente da Lucene.NET, che sembra una cattiva idea (e se invece vuoi usare SQL FTS?) E se una versione futura di Lucene.NET supporta POCO?), Oppure (b) sposta i tuoi oggetti di ricerca e i repository in un diverso spazio dei nomi/assembly e usa uno strumento come AutoMapper per convertirli in oggetti di dominio. Ad ogni modo, non credo che la creazione di interfacce per gli oggetti sarebbe di grande aiuto. – Aaronaught
@Aaronaught: hai detto che Lucene.NET non richiede attributi? si tratta di un'altra domanda che ho postato (http://stackoverflow.com/questions/2356593/lucene-net-and-poco-entities) ma come si fa senza utilizzare gli attributi con Lucene.NET? –