59 messaggi dal 17 maggio 2010
allora senza ombra di dubbio MVVM...

che problemi stai incontrando?
Modificato da u235 il 12 agosto 2013 18.12 -
37 messaggi dal 08 agosto 2008
Visto che non riguardava Ef l'ho postato in un'altra domanda:

http://forum.aspitalia.com/forum/post/398919/Domain-Driven-Design-Dubbio-Modello.aspx
37 messaggi dal 08 agosto 2008
Anche su Command query separation comincio ad avere dei dubbi sulla sccelta di adottarlo o meno.

Cosa dite è meglio se apro una nuova richiesta sull'architettura complessiva?
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

AdeptusAstartes ha scritto:

Di metodologie e pattern ne sto guardando parecchi, il difficile sarà mettere tutto insieme


no, non devi per forza adottare il maggior numero di pattern. Anzi, quando si è appena conosciuto un nuovo pattern, si ha l'impulso di volerlo adottare ovunque, anche là dove non sarebbe necessario.

Ogni pattern suggerisce un approccio per risolvere un problema specifico. Se hai solo 10 entità, allora il domain driven design non è quello che ti serve perché, io immagino, il dominio non è poi così complesso da dover essere modellato su molteplici bounded contexts.

Stessa cosa per CQRS, che è una soluzione per ottimizzare e rendere più efficienti letture e scritture. Questo arriva al costo di dover implementare una seconda versione del database ottimizzata per la lettura che viene generata da un denormalizzatore. Chiediti se nel tuo caso questo aumento di complessità è giustificato o meno. Hai migliaia di utenti da dover soddisfare contemporaneamente? In questo caso potrebbe aver senso implementare CQRS ed Event Sourcing.

Una tecnologia dovrebbe essere aggiunta al sistema (e dunque aumentandolo di complessità) solo quando risolve un problema ben specifico.
Ad esempio. Fino ad ora abbiamo valutato Entity Framework ma la tua è un'applicazione WPF. Che succede se l'utente si trova fuori ufficio? La connessione diretta al database, che si trova protetto entro il firewall aziendale, non sarebbe disponibile. Il problema si potrebbe risolvere con una connessione VPN ma devi chiederti: vuoi veramente creare un accesso VPN per ogni utente, e magari per i clienti, che per nessun motivo dovrebbero entrare nella rete aziendale, seppur con privilegi limitati?

In questo caso puoi introdurre un servizio WCF o, meglio, un WCF Data Service, accessibile da web e perciò consumabile da postazioni esterne. Se l'accesso dall'esterno della LAN aziendale è un requisito, ecco che si rende necessario introdurre un webservice.

E così via, di fonte ad un problema chiediti: "quale soluzione potrei adottare?" o "Non c'è un modo migliore per farlo?". Cercando sul web salteranno fuori varie metodologie che dovrai passare ad un secondo screening: se siano realmente utili nel tuo caso specifico e per far questo devi affrontare un piccolo percorso di ricerca per portare alla luce le potenzialità e arginare le criticità.

ciao,
Moreno
Modificato da BrightSoul il 13 agosto 2013 15.32 -

Enjoy learning and just keep making
1.495 messaggi dal 27 dicembre 2005
Al posto di WCF Data Service non sarebbero meglio le Web Api ?
37 messaggi dal 08 agosto 2008
BrightSoul ha scritto:

no, non devi per forza adottare il maggior numero di pattern. Anzi, quando si è appena conosciuto un nuovo pattern, si ha l'impulso di volerlo adottare ovunque, anche là dove non sarebbe necessario.

Più che alto ho voluto vedere lo stato dell'arte dello sviluppo con .net, vendo dallo sviluppo di sole applicazioni asp.net.

Il test driven desing ad esempio mi ha attirato subito, fino ad ora i test li abbiamo sempre snobbati relegandoli alla fine dello sviluppo senza mai implementarli davvero.
L'idea di partire dal test e poi creare gli oggetti da li tramite la creazione automatica di MS mi è piaciuta molto.

Da qui mi sono messo a cercare quale strumento usare per i test, avevo pensato a NUnit ma forse prima userò VS nudo e crudo per vedere se mi basta


Ogni pattern suggerisce un approccio per risolvere un problema specifico. Se hai solo 10 entità, allora il domain driven design non è quello che ti serve perché, io immagino, il dominio non è poi così complesso da dover essere modellato su molteplici bounded contexts.


La parte di DDD che voglio applicare è quella di modellare prima gli oggetti e non il db.
Fino ad ora ho sempre creato prima le tabelle e poi creto gli oggetti identici alle tabelle, vorrei provare a cambiare ottica e vedere come mi trovo (per ora ho i problemi messi nell'altro post)


Stessa cosa per CQRS, che è una soluzione per ottimizzare e rendere più efficienti letture e scritture.

Già deciso di abbandonarla, leggendo la prima volta mi era parso interessante come concetto ma analizzando poi l'implementazione mi sono reso conto che il progetto non ne vale lo sforzo


Una tecnologia dovrebbe essere aggiunta al sistema (e dunque aumentandolo di complessità) solo quando risolve un problema ben specifico.
Ad esempio. Fino ad ora abbiamo valutato Entity Framework ma la tua è un'applicazione WPF. Che succede se l'utente si trova fuori ufficio?

Per mia grande fortuna gli utenti possono lavorare solo da pc dell'azienda e all'interno dell'azienda, un problema in meno, motivo per cui non ho considerato WCF


E così via, di fonte ad un problema chiediti: "quale soluzione potrei adottare?" o "Non c'è un modo migliore per farlo?". Cercando sul web salteranno fuori varie metodologie che dovrai passare ad un secondo screening: se siano realmente utili nel tuo caso specifico e per far questo devi affrontare un piccolo percorso di ricerca per portare alla luce le potenzialità e arginare le criticità.


Giusto, solo che ora sono a questo punto:
Problema: devo creare un'applicazione, come la strutturo?

Soluzione:
MVVM per interfaccia
Business layer
Data Access Layer
Domain Layer

ma
come creo il domain layer?
Parto dal db? Parto dagli oggetti? Quale logica devo mettere negli oggetti?

Dopo essermi letto "Building Enterpise Application with WPF and MVVM" ho forse capito quale è la logica di dominio ma come faccio la validazione?
Solo con attributi sulle proprietà degli oggetti? Creao un interfaccia comune con la validazione standard e un'interfaccia per ogni oggetti con la validazione specifica?

Sempre nel libro ho letto delle fluent interface e mi sono piaciute ma le applico anche qui??

Pensando poi al DAL (e volendo andare sulla strada EF) ho capito che devo mettere delle proprietà sugli oggetti per far creare il db in maniera migliore (vedi campi testo con lunghezza ridotta o text), ma devo metterle sugli oggetti o posso metterli sull'interfaccia usata per la validazione.

Altra cosa che mi ha interessato è la dependency injection (e l'inversion of control in generale) visto che fino ad oggi le interfacce mi erano sembrate quasi inutili, mentre in questo modo diventano veramente ottime per separare i livelli soprastanti dalle implementazioni.
Ma qui come le incastro con il resto?

Queste sono le cose che vorrei riuscire a capire, altrimenti non so nemmeno cosa quali test devo fare nel mio approccio TDD
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

totti240282 ha scritto:

Al posto di WCF Data Service non sarebbero meglio le Web Api ?

Sì, si potrebbe usare anche una Web API. In questo caso ho suggerito un WCF Data Service perché avendo un'applicazione WPF magari voleva usare un trasporto diverso da HTTP, anche perché fino a questo momento non si è parlato di un server web. WCF puoi ospitarlo anche in un servizio per Windows o in un progetto Console, quindi in mancanza di ulteriori dettagli mi sono tenuto sulla soluzione più versatile.

AdeptusAstartes ha scritto:

Per mia grande fortuna gli utenti possono lavorare solo da pc dell'azienda e all'interno dell'azienda, un problema in meno, motivo per cui non ho considerato WCF

Bene così :)

AdeptusAstartes ha scritto:

come creo il domain layer?
Parto dal db? Parto dagli oggetti?

Parti dagli oggetti (si dovrebbe dire classi di entità perché gli oggetti, o entità, sono istanze di quelle classi).

AdeptusAstartes ha scritto:

ho forse capito quale è la logica di dominio

Una classe non è soltanto una collezione di proprietà ma può (e dovrebbe) possedere della logica di business, cioè metodi che ne espongano il comportamento e che, come conseguenza della loro invocazione, modificano lo stato interno dell'entità.

Faccio un esempio.
Tu dici di avere un'entità Controllo che viene avviata su entità Processo. Concentriamoci su Controllo: l'approccio più intuitivo è quello di creare nella classe una proprietà chiamata Conclusa di tipo booleano, il cui valore predefinito è false ma viene impostata a true nel momento in cui l'utente decide che quel controllo è stato completato.

In realtà progettare lo status del Controllo in questo modo già vìola una delle raccomandazioni del DDD, cioè l'Ubiquitous Language. Tu non troverai mai un committente che ti dice "Quando il controllo è completo, io scrivo true sulla scheda".

Un miglioramento che potresti fare è quello di rinominare la proprietà "Concluso" in "Status" (o qualsiasi altro termine usiate) cambiare il tipo da booleano ad un'enumerazione che preveda le voci InCorso e Completo. EF5 supporta le enumerazioni e in questo modo consenti l'aggiunta di altre voci che potrebbero rendersi necessarie in futuro (es. InPausa, Cancellato).

Già sei più aderente al principio dell'Ubiquitous Language se il committente ti dice: "Quando il controllo è completo io scrivo 'Completo' sulla scheda".

Tuttavia quest'affermazione nasconde qualcosa di più complesso, che solitamente viene rivelato dopo alcuni incontri con il committente.
Ci saranno certamente delle situazioni in cui il Controllo non può essere completato perché non sono state svolte determinate operazioni, come fornire dei documenti d'appoggio od un'esito finale.

Alcuni progetti vanno incontro a bug e serie difficoltà se lo svilippatore pensa che la situazione sia semplice e chiara fin dal principio, ed inizia a scrivere righe di codice come questa:
controllo.Status = Status.Completo;

Questa riga di codice cambia il valore di Status in maniera permanente e ignora tutte le precondizioni necessarie affinché lo Status possa essere spostato su Completo. Questo codice è pericoloso perché riesce a completare un Controllo anche se non c'erano i requisiti per farlo.

Un modo migliore per gestire questa situazione è esporre un metodo Completa() che verrà invocato da un apposito bottone (guardati la metodologia di design chiamata task-based UI)
controllo.Completa();


Inizialmente l'implementazione del metodo nella classe Controllo sarà semplicemente questa.
public void Completa(){
   this.Status = Status.Completo;
}

Che sembra una complicanza inutile, ma ti aiuterà moltissimo nel futuro, quando verrai a conoscenza di requisiti che non erano emersi nei primi incontri col committente.

Se lui ad un certo punto ti dicesse: "No, guarda, non ci eravamo capiti ma per poter completare un Controllo c'è bisogno che il tecnico abbia caricato un documento e che fornisca l'esito del controllo".

A questo punto puoi integrare il corpo del metodo Completa di tutta la nuova logica di business ed eventualmente modificarne il numero di parametri.

[Obsolete("Non più supportato, devi fornire un esito", true)]
public void Completa(){
  throw new Exception("Non più supportato, devi fornire un esito");
}

public void Completa(Esito esito){
   
    if (this.DocumentoDiAppoggio == null)
      throw new ImpossibileCompletareException("Manca il documento di appoggio");

   this.Status = Status.Completo;
}

In questo modo la logica è incapsulata nella classe. Se non l'avessi fatto, saresti dovuto andarti a trovare tutti i punti, nella tua applicazione, in cui si assegnava lo Status a Completato, e modificare quella logica esternamente. Capisci se fai lo sforzo di non usare i setter delle proprietà ma i metodi della classe, sarai meno esposto a problemi.

Anche per un semplice cambio password, predisponi il metodo CambiaPassword perché dovrà comunque incapsulare un minimo di logica, tipo controllare che la nuova password non sia identica a quella fornita e che raggiunga i criteri minimi di sicurezza.

Dunque, per ripendere la tua domanda:
AdeptusAstartes ha scritto:

come creo il domain layer?
Parto dal db? Parto dagli oggetti?

Parti dalle classi di entità, iniziando a modellare prima quelle il cui comportamento ti sembra sufficientemente chiaro.
Anzi, dato che vuoi impiegare il Test Driven Development scrivi prima il test e lasciallo fallire (questo è utile perché richiede che tu abbia ragionato sull'uso che andrai a fare del metodo). Solo POI implementa la logica di business nei metodi di cui abbiamo parlato. Se tutto è stato fatto correttamente, il test passerà.

AdeptusAstartes ha scritto:

Sempre nel libro ho letto delle fluent interface e mi sono piaciute ma le applico anche qui??

Dipende. L'esperto di dominio è il committente, devi ascoltare come parla e capire se un'interfaccia fluente può fare al caso tuo.
Se ti dice:
"Io, quando creo un controllo, scelgo prima il processo e poi gli assegno due persone che dovranno seguirlo. Poi scelgo una data di inizio e faccio una previsione sulla data di fine. In ultimo, imposto un numero massimo di ore al giorno da destinargli."
Allora, dato che la costruizione è un processo a più fasi, potrebbe aver senso crearsi una factory, eventualmente con interfaccia fluente.
var nuovoControllo = 
  servizioCreazioneControllo  //questa istanza mi viene fornita dal container IoC. Programma contro interfacce, non contro implementazioni concrete
  .DaProcesso(processo)
  .AssegnaPersonale(impiegato1, impiegato2)
  .IniziaIl(DateTime.Today)
  .FinePrevistaIl(DateTime.Today.AddDays(20))
  .PerUnMassimoDiOreGiornaliere(2)
  .Crea();

Che tu usi l'interfaccia fluente o no, delegare la costruzione ad una factory, in questo caso, ti permette di racchiudere in essa della logica che non è di stretta pertinenza dell'entità Controllo. Ad esempio, se impiegato1 fosse già impegnato in altri progetti e non potrebbe dedicare 2 ore al giorno a quel Controllo, è la factory che dovrebbe lanciare un'eccezione.

ciao,
Moreno
Modificato da BrightSoul il 19 agosto 2013 00.18 -

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.