Domain Driven Design - Migliorare il lavoro degli sviluppatori

6

Mi sono imbattuto in un'architettura per un'applicazione .net in cui ci sono 3 livelli

Repository layer (edmx and their classes)
      ^
      |
      V
Domain layer (Model -> Interfaces and their implementation)
      ^
      |
      V
Web layer (Model -> View models)

La comunicazione tra il web e il livello dati avviene tramite interfacce definite nel livello dominio ( modelli anemici )

La convenzione di denominazione utilizzata qui dipende dai nomi delle tabelle

Livello repository

TableNameRepository.cs

TableName.cs (file generati automaticamente)

DomainLayer

ITableName.cs

TableName.cs

TableNameService.cs

Livello Web

TableNameListModel

TableNameAddEditModel

Il problema è che se una tabella viene modificata nella tabella, tutte le classi nel repository e nei livelli di dominio devono essere riutilizzate.

Inoltre, la comunicazione tra questi livelli avviene con i manager che sono stati risolti come segue, dove Container è statico

Container.Resolve<RepositoryManager>();
Container.Resolve<ServiceManager>();

Il DBContext è memorizzato nelle variabili di sessione durante la prima chiamata e rimosso alla fine della richiesta. La seconda chiamata inizializzerà DBContext con l'operatore new .

Qualche suggerimento su cosa può essere fatto (con modifiche minime) in modo da imporvi questa architettura in modo che sia allineata con DDD.

    
posta gvk 28.04.2017 - 10:51
fonte

2 risposte

1

Difficile dire dal tuo esempio, ma questo sembra un progetto abbastanza standard.

La mia unica preoccupazione riguarda le classi manager e dbContext che normalmente sarebbero nascoste nel repository.

Come "renderlo più DDD" hai un problema nel fatto che DDD vorrebbe che tu fossi molto OO e sostanzialmente spostare il livello di servizio nell'oggetto entità. Ma questo non funziona bene con un servizio web / web.api basato su chiamate stateless a un servizio.

Tuttavia non mi preoccuperei troppo, in quanto è davvero solo un problema di denominazione e può essere risolto includendo gli oggetti di servizio nella progettazione. cioè piuttosto che acquistare un ordine ( Order.Purchase() ), fino a completare un ordine ( Till.Complete(order) )

Problema 1

"if a column is modified in the table, the classes in repository and domain layers all need re-work."

Questo è come dovrebbe essere, il database memorizzava i modelli, quindi se ne cambi uno cambia l'altro e viceversa.

Se si sta lavorando con un sistema di database legacy è possibile aggirare il problema in una certa misura facendo in modo che il repository richiami le stored procedure piuttosto che le tabelle direttamente. Questo ti dà uno strato (aggiuntivo) di astrazione tra le tabelle e i modelli

Problema # 2

communication between these layers take place with managers which have been resolved as below, where Container is static

Questo è un po 'brutto. Dovresti usare una classe Factory per istanziare il tuo livello web, (assumendo C # mvc Controllers?) Che conosce il contenitore e recupera e inietta le classi richieste. Questo evita di avere il riferimento statico e le chiamate ad esso.

    
risposta data 29.04.2017 - 06:30
fonte
0

Vorrei iniziare con un esercizio di carta: disegnare un modello di oggetto completo in modo da comprendere appieno l'architettura.

Quindi proverei a vedere se esistessero contesti naturali limitati che diventassero evidenti. Quindi prova ad implementare un nuovo contesto limitato accanto al codice esistente, con nuove classi di dominio secondo necessità e incapsula le regole di business all'interno degli oggetti di dominio (supponendo che queste regole siano altrove).

Supponendo che tutto vada bene, il nuovo contesto limitato dovrebbe essere in grado di sostituire una parte definita del codice esistente, che puoi rimuovere in seguito.

Quindi ripeti se necessario.

Personalmente, vorrei TDD mentre andavo avanti, poiché mi avrebbe aiutato ad esaminare qualsiasi ipotesi che avevo fatto.

    
risposta data 28.07.2017 - 10:12
fonte