Dove tracciamo il confine tra delega e incapsulamento della logica aziendale? Mi sembra che più deleghiamo, più diventiamo anemici . Tuttavia, la delegazione promuove anche il riutilizzo e il principio DRY. Quindi, cosa è appropriato delegare e cosa dovrebbe rimanere nei nostri modelli di dominio?
Prendi le seguenti preoccupazioni come esempi:
Autorizzazione . L'oggetto dominio dovrebbe essere responsabile del mantenimento delle regole di controllo dell'accesso (come una proprietà CanEdit) o dovrebbe essere delegato a un altro componente / servizio l'unico responsabile della gestione dell'accesso, ad esempio IAuthorizationService.CanEdit (oggetto)? O dovrebbe essere una combinazione dei due? Forse l'oggetto del dominio ha una proprietà CanEdit che delega a un IAuthorizationService interno per eseguire il lavoro effettivo?
Convalida . La stessa discussione di cui sopra si riferisce alla convalida. Chi mantiene le regole e chi è responsabile della loro valutazione? Da un lato, lo stato dell'oggetto dovrebbe appartenere a quell'oggetto e la validità è uno stato, ma non vogliamo riscrivere il codice utilizzato per valutare le regole per ogni oggetto di dominio. Abbiamo potuto utilizzare l'ereditarietà in questo caso ...
Creazione di oggetti . Classe di fabbrica rispetto ai metodi di fabbrica rispetto alla "novità" di un'istanza. Se utilizziamo una classe factory separata, siamo in grado di isolare e incapsulare la logica di creazione, ma a spese dell'apertura dello stato del nostro oggetto alla factory. Questo può essere gestito se il nostro livello di dominio si trova in un assembly separato esponendo un costruttore interno utilizzato dalla fabbrica, ma ciò diventa un problema se esistono più modelli di creazione. E, se tutto ciò che la fabbrica sta facendo è chiamare il costruttore giusto, che senso ha avere la fabbrica?
I metodi factory sulla classe eliminano il problema con l'apertura dello stato interno dell'oggetto, ma poiché sono statici, non siamo in grado di rompere le dipendenze attraverso l'iniezione di un'interfaccia factory come possiamo con una classe factory separata.
Persistenza . Si potrebbe sostenere che se il nostro oggetto di dominio sta per esporre CanEdit mentre delega la responsabilità di eseguire il controllo di autorizzazione a un'altra parte (IAuthorizationService) perché non avere un metodo Save sul nostro oggetto di dominio che fa la stessa cosa? Ciò ci consentirebbe di valutare lo stato interno dell'oggetto per determinare se l'operazione può essere eseguita senza interrompere l'incapsulamento. Ovviamente è necessario che iniettiamo l'istanza del repository nel nostro oggetto dominio, il che ha un odore un po 'per me, quindi generiamo un evento di dominio e consentiamo a un gestore di eseguire l'operazione di persistenza?
Vedi dove sto andando con questo?
Rockford Lhotka ha una grande discussione sulle sue ragioni per seguire la rotta Class-in-Charge per il suo framework CSLA e io ho un po 'di storia con quel framework e posso vedere la sua idea di oggetti business in parallelo a oggetti di dominio in molti modi. Ma cercando di diventare più aderente ai buoni ideali di DDD, mi chiedo quando la collaborazione diventa troppo.
Se finisco con un IAuthorizationService, IValidator, IFactory e IRepository per la mia radice aggregata, cosa rimane? Avere un metodo di pubblicazione che modifica lo stato dell'oggetto da Bozza a Pubblicato è abbastanza per considerare la classe un oggetto di dominio non anemico?
I vostri pensieri?