Non discuto le notevoli capacità di zio brando, ma quando ho cercato il suo blog
su google con questa chiave "brandolini zio brando blog" e google mi ha risposto
Forse cercavi: "brandolini DIO brando blog" mi è sembrato eccessivo! ;-)
Dio Brando e' effettivamente un personaggio dei fumetti =)
Da: Daniele Armanasco <daniele@...> A: DDD-IT@yahoogroups.com Inviato: Gio 7 aprile 2011, 16:19:28 Oggetto: [DDD-IT] [OT] Google e la ricerca del blog di zio brando ...
Non discuto le notevoli capacità di zio brando, ma quando ho cercato il suo blog su google con questa chiave "brandolini zio brando blog" e google mi ha risposto Forse cercavi: "brandolini DIO brando blog" mi è sembrato eccessivo! ;-)
Il giorno 07/apr/2011, alle ore 16:42, Gianluigi <davassi@...> ha scritto:
Dio Brando e' effettivamente un personaggio dei fumetti =)
Da: Daniele Armanasco <daniele@...> A:DDD-IT@yahoogroups.com Inviato: Gio 7 aprile 2011, 16:19:28 Oggetto: [DDD-IT] [OT] Google e la ricerca del blog di zio brando ...
Non discuto le notevoli capacità di zio brando, ma quando ho cercato il suo blog su google con questa chiave "brandolini zio brando blog" e google mi ha risposto Forse cercavi: "brandolini DIO brando blog" mi è sembrato eccessivo! ;-)
mi si è accesa una piccola lampadina durante l'ultimo corso DDD a Londra.
Uno dei partecipanti, che stava già facendo DDD, è arrivato con una sfilza di domande provenienti dal team. Legate a "chi deve lanciare gli eventi", "come si devono mappare le relazioni gerarchiche" e così via. Cose che ricadono dell'ambito delle "domande più frequenti".
In generale, ho sempre pensato che fossero frequenti, perché ci sono aspetti su cui DDD non si pronuncia esplicitamente. Perché non c'è un "libro ufficiale su come fare DDD in Java" (e credo che questa asimmetria abbia aiutato la diffusione su .Net) e così via. Parlando della cosa con Eric era però evidente che lui non avesse voluto sbilanciarsi sulla parte pratica, perché il vero problema stava altrove. D'altro canto, DDD deve essere indipendente dalla tecnologia, quindi c'è anche il costo di manutenzione della documentazione di cui tenere conto.
Un punto però stava saltando fuori con una certa insistenza: DDD non è solo un insieme di pattern. Anzi, a dirla tutta, i pattern sono una naturale conseguenza dei principi. Se si applicano solo i pattern (cosa che leggendo solo la prima parte del libro, o il bignamino di InfoQ può capitare) si fa qualcosa che assomiglia a DDD, ma che DDD non è. Il punto chiave è molto più probabilmente riuscire a stabilire una "creative collaboration" con i domain expert.
Sentendomi ripetere ancora una volta una domanda tecnica, mi sono chiesto: "Ma perché mi chiedono questa cosa?", cioè: io la risposta non la sapevo. :-) Se ho quel problema, ...provo. Se funziona sono a posto. Se non funziona sono comunque in un aggregato con poche dipendenze esterne, e non appena scopro qualcosa di meglio lo riscrivo.
La cosa di cui mi sono reso conto è che in molti casi la domanda tecnica nasconde un'insicurezza di fondo. Che porta a voler cercare quanto prima una situazione sicura (ho fatto come dice il libro) anziché accettare il fatto di trovare una sensazione "tentativo" e di tenersi aperta la possibilità di cambiare. In realtà quello che serve non è la sicurezza di fare le cose giuste. Ma la tranquillità di poter sbagliare. Ed ovviamente di imparare dagli errori fatti.
lavoro da alcuni con domain model finanziari per banche (su .NET). Sono assolutamente d'accordo che ovviamente il punto fondamentale del DDD è stabilire una buona comunicazione con il domain expert.
Tuttavia, dopo tanti errori, noi abbiamo raccolto una serie di "pattern" modellativi che hanno mostrato di funzionare bene (nonché un enorme serie di anti-pattern che sembrano gran furbate sulle prime e risultano devastanti dopo due settimane)
Tali pattern, una volta condivisi hanno permesso di ridurre notevolmente la curva di apprendimento della metodologia.
Alla fine, in estrema sintesi, se il codice che usa il dominio non è "leggibile" dall'esperto, è sbagliato.
E' chiaro che essendo pattern "casalinghi" non hanno l'autorevolezza di un libro stampato (e solo la produttività concreta che hanno dimostrato ha reso possibile la loro diffuzione nella nostra azienda).
Purtroppo, di questi tempi, con commerciali che vendono sistematicamente al ribasso, la tranquillità di sbagliare da noi non c'è. E senza questi pattern, di fatto, molti colleghi avrebbero probabilmente rifiutato nei fatti la metodologia in toto.
Senza capacità di rispondere anche su aspetti tecnici (magari ragionando insieme a chi pone un problema, cercando insieme soluzioni generali), si perde credibilità personale (che purtroppo spesso nella pratica, viene identificata con la credibilità e la validità della metodologia stessa).
D'altronde che cos'è la responsabilità se non la capacità di rispondere?
Devo dire comunque, che l'assenza di framework mainstream seriamente orientati al DDD e che non richiedano di essere combattuti, faciliterebbe.
La maggioranza degli sviluppatori (me compreso) preferisce le strade battute. Personalmente tutte le volte che me ne discosto devo avere ottime ragioni per farlo. E quando capita, mi rendo conto di quanto giovane sia la nostra "attività artigiana".
Lo sviluppo software, checché ne dicano i grandi vendor è appena alla preistoria...
mi si è accesa una piccola lampadina durante l'ultimo corso DDD a Londra.
Uno dei partecipanti, che stava già facendo DDD, è arrivato con una sfilza di domande provenienti dal team. Legate a "chi deve lanciare gli eventi", "come si devono mappare le relazioni gerarchiche" e così via. Cose che ricadono dell'ambito delle "domande più frequenti".
In generale, ho sempre pensato che fossero frequenti, perché ci sono aspetti su cui DDD non si pronuncia esplicitamente. Perché non c'è un "libro ufficiale su come fare DDD in Java" (e credo che questa asimmetria abbia aiutato la diffusione su .Net) e così via. Parlando della cosa con Eric era però evidente che lui non avesse voluto sbilanciarsi sulla parte pratica, perché il vero problema stava altrove. D'altro canto, DDD deve essere indipendente dalla tecnologia, quindi c'è anche il costo di manutenzione della documentazione di cui tenere conto.
Un punto però stava saltando fuori con una certa insistenza: DDD non è solo un insieme di pattern. Anzi, a dirla tutta, i pattern sono una naturale conseguenza dei principi. Se si applicano solo i pattern (cosa che leggendo solo la prima parte del libro, o il bignamino di InfoQ può capitare) si fa qualcosa che assomiglia a DDD, ma che DDD non è. Il punto chiave è molto più probabilmente riuscire a stabilire una "creative collaboration" con i domain expert.
Sentendomi ripetere ancora una volta una domanda tecnica, mi sono chiesto: "Ma perché mi chiedono questa cosa?", cioè: io la risposta non la sapevo. :-) Se ho quel problema, ...provo. Se funziona sono a posto. Se non funziona sono comunque in un aggregato con poche dipendenze esterne, e non appena scopro qualcosa di meglio lo riscrivo.
La cosa di cui mi sono reso conto è che in molti casi la domanda tecnica nasconde un'insicurezza di fondo. Che porta a voler cercare quanto prima una situazione sicura (ho fatto come dice il libro) anziché accettare il fatto di trovare una sensazione "tentativo" e di tenersi aperta la possibilità di cambiare. In realtà quello che serve non è la sicurezza di fare le cose giuste. Ma la tranquillità di poter sbagliare. Ed ovviamente di imparare dagli errori fatti.
Il giorno 14 aprile 2011 17:54, Giacomo Tesio <giacomo@...> ha scritto:
Ciao,
lavoro da alcuni con domain model finanziari per banche (su .NET). Sono assolutamente d'accordo che ovviamente il punto fondamentale del DDD è stabilire una buona comunicazione con il domain expert.
Tuttavia, dopo tanti errori, noi abbiamo raccolto una serie di "pattern" modellativi che hanno mostrato di funzionare bene (nonché un enorme serie di anti-pattern che sembrano gran furbate sulle prime e risultano devastanti dopo due settimane)
Tali pattern, una volta condivisi hanno permesso di ridurre notevolmente la curva di apprendimento della metodologia.
Alla fine, in estrema sintesi, se il codice che usa il dominio non è "leggibile" dall'esperto, è sbagliato.
Uno degli aspetti che volevo mettere in evidenza è proprio questo. Avete sperimentato, e mi sembra che la conseguenza sia una consapevolezza più profonda di "Eric nel libro ha detto di non fare questa cosa".
E' chiaro che essendo pattern "casalinghi" non hanno l'autorevolezza di un libro stampato (e solo la produttività concreta che hanno dimostrato ha reso possibile la loro diffuzione nella nostra azienda).
Purtroppo, di questi tempi, con commerciali che vendono sistematicamente al ribasso, la tranquillità di sbagliare da noi non c'è.
Hai anche già indicato il problema. Se abbassi troppo gli spazi di manovra, di fatto stai ipotizzando il progetto in cui non puoi permetterti di sbagliare nulla. Ovvero una condizione perfetta per sbagliare e non poter correggere. Per certi versi simile alla partita dell'Inter di ieri sera.
E senza questi pattern, di fatto, molti colleghi avrebbero probabilmente rifiutato nei fatti la metodologia in toto.
... qui ti chiederei di espandere. Cosa avrebbero rifiutato, ed a favore di cosa?
Senza capacità di rispondere anche su aspetti tecnici (magari ragionando insieme a chi pone un problema, cercando insieme soluzioni generali), si perde credibilità personale (che purtroppo spesso nella pratica, viene identificata con la credibilità e la validità della metodologia stessa).
E' chiaro che la parte tecnica serve. Ma è anche vero che molto spesso gli aspetti vengono eccessivamente sovrapposti. Ricordo una discussione abbastanza accesa a Better Software l'anno scorso riguardo al fatto che il Coach dovesse dare anche una guida tecnica. Il ruolo del coach dovrebbe essere quello di far crescere il team, trovando i propri punti di forza. Essere ancheuna guida tecnica potrebbe essere una complicazione.
Però la risposta corretta è quella che suggerisci: ragionando insieme le soluzioni si trovano. E - per capirci - a me rispondere alle domande incasinate... piace. L'aspetto che mi inquieta a volte è la ricerca di "regole".
D'altronde che cos'è la responsabilità se non la capacità di rispondere?
Ok, come classifichi l'assunzione di responsabilità di uno che ti dice: "ho fatto come dice il libro?". Io ci vedo un po' il riflesso di un ambiente che non tollera facilmente gli errori. Ho l'impressione che stiamo dicendo cose simili da angolazioni differenti.
Devo dire comunque, che l'assenza di framework mainstream seriamente orientati al DDD e che non richiedano di essere combattuti, faciliterebbe.
...intendevi la presenza?
La maggioranza degli sviluppatori (me compreso) preferisce le strade battute. Personalmente tutte le volte che me ne discosto devo avere ottime ragioni per farlo.
...beh se ho un nuovo problema, la strada battuta è un po' difficile. Non è che si vada a caccia della soluzione esplorativa "a prescindere", se con i pattern classici la cosa "fila", bene. Se ho un problema relativamente nuovo e mi trovo in difficoltà con quello che ho implementato... provo una soluzione alternativa.
E quando capita, mi rendo conto di quanto giovane sia la nostra "attività artigiana".
Lo sviluppo software, checché ne dicano i grandi vendor è appena alla preistoria...
mi si è accesa una piccola lampadina durante l'ultimo corso DDD a Londra.
Uno dei partecipanti, che stava già facendo DDD, è arrivato con una sfilza di domande provenienti dal team. Legate a "chi deve lanciare gli eventi", "come si devono mappare le relazioni gerarchiche" e così via. Cose che ricadono dell'ambito delle "domande più frequenti".
In generale, ho sempre pensato che fossero frequenti, perché ci sono aspetti su cui DDD non si pronuncia esplicitamente. Perché non c'è un "libro ufficiale su come fare DDD in Java" (e credo che questa asimmetria abbia aiutato la diffusione su .Net) e così via. Parlando della cosa con Eric era però evidente che lui non avesse voluto sbilanciarsi sulla parte pratica, perché il vero problema stava altrove. D'altro canto, DDD deve essere indipendente dalla tecnologia, quindi c'è anche il costo di manutenzione della documentazione di cui tenere conto.
Un punto però stava saltando fuori con una certa insistenza: DDD non è solo un insieme di pattern. Anzi, a dirla tutta, i pattern sono una naturale conseguenza dei principi. Se si applicano solo i pattern (cosa che leggendo solo la prima parte del libro, o il bignamino di InfoQ può capitare) si fa qualcosa che assomiglia a DDD, ma che DDD non è. Il punto chiave è molto più probabilmente riuscire a stabilire una "creative collaboration" con i domain expert.
Sentendomi ripetere ancora una volta una domanda tecnica, mi sono chiesto: "Ma perché mi chiedono questa cosa?", cioè: io la risposta non la sapevo. :-) Se ho quel problema, ...provo. Se funziona sono a posto. Se non funziona sono comunque in un aggregato con poche dipendenze esterne, e non appena scopro qualcosa di meglio lo riscrivo.
La cosa di cui mi sono reso conto è che in molti casi la domanda tecnica nasconde un'insicurezza di fondo. Che porta a voler cercare quanto prima una situazione sicura (ho fatto come dice il libro) anziché accettare il fatto di trovare una sensazione "tentativo" e di tenersi aperta la possibilità di cambiare. In realtà quello che serve non è la sicurezza di fare le cose giuste. Ma la tranquillità di poter sbagliare. Ed ovviamente di imparare dagli errori fatti.
Il giorno 14 aprile 2011 17:54, Giacomo Tesio <giacomo@...> ha scritto:
Tuttavia, dopo tanti errori, noi abbiamo raccolto una serie di "pattern" modellativi che hanno mostrato di funzionare bene (nonché un enorme serie di anti-pattern che sembrano gran furbate sulle prime e risultano devastanti dopo due settimane)
Tali pattern, una volta condivisi hanno permesso di ridurre notevolmente la curva di apprendimento della metodologia.
Alla fine, in estrema sintesi, se il codice che usa il dominio non è "leggibile" dall'esperto, è sbagliato.
Uno degli aspetti che volevo mettere in evidenza è proprio questo. Avete sperimentato, e mi sembra che la conseguenza sia una consapevolezza più profonda di "Eric nel libro ha detto di non fare questa cosa".
Alla luce delle nostre sperimentazioni abbiamo anche compreso che il libro di Evans non è affatto "esaustivo" (sebbene FONDAMENTALE). Prendiamo ad esempio la mutabilità di un valueobject. Nel libro si _consiglia_ di renderli immutabili: noi un paio di volte abbiamo pensato che fosse sensato allontanarsi da questo consiglio, con effetti devastanti di lì ad un mese.
Così come sulle referenze circolari fra entità (sconsigliate, ma non "vietate"), per fare esempi semplici che però hanno bruciato settimane di lavoro in refactoring. Oppure la centralità di boundary context ben definiti ed in dipendenti a priori (cosa ben spiegata nel libro, ma forse senza la sufficiente enfasi, quasi che sia più importante del concetto di entità/value object, direi).
Siamo giunti alla conclusione che ogni volta che la rappresentazione del dominio fatica ad adottare questi pattern (ed altri pattern casalinghi) c'è da qualche parte un errore di comprensione del modello di business stesso.
E nell'ultimo anno, quando questo succede, riprendiamo la discussione dall'inizio con il domain expert.
Questo semplicemente perché abbiamo osservato che è più economico!
E' chiaro che essendo pattern "casalinghi" non hanno l'autorevolezza di un libro stampato (e solo la produttività concreta che hanno dimostrato ha reso possibile la loro diffuzione nella nostra azienda).
Purtroppo, di questi tempi, con commerciali che vendono sistematicamente al ribasso, la tranquillità di sbagliare da noi non c'è.
Hai anche già indicato il problema. Se abbassi troppo gli spazi di manovra, di fatto stai ipotizzando il progetto in cui non puoi permetterti di sbagliare nulla. Ovvero una condizione perfetta per sbagliare e non poter correggere. Per certi versi simile alla partita dell'Inter di ieri sera.
Vero, il rischio di degradare in tale condizione esiste (ed è pure capitato in un progetto).
Tuttavia abbiamo imparato così bene l'importanza del modello dominio che su quello cerchiamo di non sbagliare.
E se ci accorgiamo di un errore potenziale, fermiamo tutto (con sommo terrore e grande disapprovazione dei commerciali) e riprendiamo l'analisi con l'esperto di dominio.
Questi pattern "stringenti" servono quasi da cartina tornasole: se fatichiamo ad adottarli, capiamo che abbiamo frainteso qualcosa del modello stesso e cerchiamo subito un deeper insight.
E senza questi pattern, di fatto, molti colleghi avrebbero probabilmente rifiutato nei fatti la metodologia in toto.
... qui ti chiederei di espandere. Cosa avrebbero rifiutato, ed a favore di cosa?
Noi lavoriamo anche per l'industria e l'energia.
In questi ambiti, molto spesso le applicazioni che abbiamo sviluppato finora sono molto data driven. Ed in effetti tipicamente i nostri dba dettano quasi legge! :-D
Alcuni programmatori che si sono trasferiti lo scorso anno dal settore energia alla finanza hanno opposto una certa resistenza ad allontanarsi da un modello DB -> servizi SOA (procedurali) -> GUI sostanzialmente rad.
Solo la enorme complessità dei problemi che si sono trovati davanti (come gestire le sessioni di consulenza mifid per i private banker di una grande banca) li ha convinti che un approccio del genere non funzionava (in tempi e qualità compatibili con l'esigenze del cliente).
Senza capacità di rispondere anche su aspetti tecnici (magari ragionando insieme a chi pone un problema, cercando insieme soluzioni generali), si perde credibilità personale (che purtroppo spesso nella pratica, viene identificata con la credibilità e la validità della metodologia stessa).
E' chiaro che la parte tecnica serve. Ma è anche vero che molto spesso gli aspetti vengono eccessivamente sovrapposti. Ricordo una discussione abbastanza accesa a Better Software l'anno scorso riguardo al fatto che il Coach dovesse dare anche una guida tecnica. Il ruolo del coach dovrebbe essere quello di far crescere il team, trovando i propri punti di forza. Essere ancheuna guida tecnica potrebbe essere una complicazione.
Però la risposta corretta è quella che suggerisci: ragionando insieme le soluzioni si trovano. E - per capirci - a me rispondere alle domande incasinate... piace. L'aspetto che mi inquieta a volte è la ricerca di "regole".
Personalmente sono molto più critico rispetto alle "regole" di processo che ai pattern di modellazione.
Fin ora tutti i tentativi di rendere più Agile i processi di sviluppo del settore finanza sono falliti miseramente (contrariamente a quanto avviene nel settore industria, per esempio).
Se è evidente a tutti che il valore sta nelle persone che lavorano nel team, la complessità dei problemi che affrontiamo (e forse anche la dimensione degli applicativi che stiamo vendendo di recente) sfugge alle metodologie tanto decantate da altri.
Noi ci siamo trovati ad essere una specie di scatola nera nell'aziende: in ogni iterazione buttano dentro specifiche di altissimo livello -> rompiamo le balle al domain expert fin quando basta -> diamo dei tempi -> rispettiamo i tempi -> il cliente è soddisfatto.
Quando il management ha cercato di risparmiare sull'analisi di dominio, tutte le volte abbiamo finito per rifare il lavoro (in un caso ben tre volte!).
L'unico aspetto del processo che seguiamo sempre è l'assoluta priorità del dominio rispetto al resto (db, servizi, gui etc).
Fin quando non ci è _chiaro_ il dominio del problema non diamo nemmeno i tempi!
D'altronde che cos'è la responsabilità se non la capacità di rispondere?
Ok, come classifichi l'assunzione di responsabilità di uno che ti dice: "ho fatto come dice il libro?". Io ci vedo un po' il riflesso di un ambiente che non tollera facilmente gli errori. Ho l'impressione che stiamo dicendo cose simili da angolazioni differenti.
Mah.. ho la fortuna di lavorare in un azienda in cui abbiamo investito circa 20 mesi uomo per sviluppare un framework interno per sviluppare rapidamente GUI basate su domini fortemente tipizzati e molto complessi. Apparentemente follia pura!
Eppure è stata una decisione ben ponderata, perché i prodotti disponibili sul mercato non permettevano la produttività di cui avevamo bisogno.
Ho partecipato personalmente alla progettazione ed allo sviluppo di tale framework ed eravamo tutti coscienti (management incluso) dei rischi di tale percorso.
Non siamo mai stati "cazziati" per gli errori che abbiamo fatto (ed i conseguenti refactoring della codebase che abbiamo causato).
Ma credo sia il mercato a non tollerare certi errori. Ogni banca da cui andiamo ha dei processi mastodontici di approvazione degli applicativi!
Ogni deploy è vissuto come "che bello, oggi andiamo al ministero"! E la concorrenza è spietata. Noi puntiamo all'eccellenza (da ben prima del mio arrivo in azienda), ma abbiamo dovuto fare i conti con una concorrenza basata sul prezzo (e sui tempi di consegna).
Siamo tutti coscienti di essere stati molto fortunati ad uscirne vivi (e fortunatamente arzilli :-D).
Devo dire comunque, che l'assenza di framework mainstream seriamente orientati al DDD e che non richiedano di essere combattuti, faciliterebbe.
...intendevi la presenza?
Sì, scusa. Tutto ciò che trovo in giro è ben lungi dalle nostre esigenze (in finanza).
La maggioranza degli sviluppatori (me compreso) preferisce le strade battute. Personalmente tutte le volte che me ne discosto devo avere ottime ragioni per farlo.
...beh se ho un nuovo problema, la strada battuta è un po' difficile. Non è che si vada a caccia della soluzione esplorativa "a prescindere", se con i pattern classici la cosa "fila", bene. Se ho un problema relativamente nuovo e mi trovo in difficoltà con quello che ho implementato... provo una soluzione alternativa.
Alcune volte le strade battute sono sbagliate. Ti potrei fare un breve elenco di pattern battutissimi, ma che abbiamo dovuto abbiamo dovuto abbandonare a ragion veduta.
Un esempio sempre sconcertante quando condividiamo il nostro approccio con i colleghi del settore energia: l'event EventBroker è un (anti)pattern per disaccoppiare dagli eventi .NET. _Sul domain model_ è una soluzione ad un sintomo. Ma abbiamo compreso che genera più problemi di quanti non ne risolva.
Così abbiamo dovuto risalire al problema vero e risolverlo alla base.
E quando capita, mi rendo conto di quanto giovane sia la nostra "attività artigiana".
Lo sviluppo software, checché ne dicano i grandi vendor è appena alla preistoria...
Questo decisamente, ma la crescita è veloce :-)
Non sono così d'accordo. Volendo fare un paragone con l'architettura classica, siamo ancora a Micene, intorno al 1400 A.C.
Il giorno 15 aprile 2011 10:22, Giacomo Tesio <giacomo@...> ha scritto:Il giorno 14 aprile 2011 17:54, Giacomo Tesio <giacomo@...> ha scritto:
Tuttavia, dopo tanti errori, noi abbiamo raccolto una serie di "pattern" modellativi che hanno mostrato di funzionare bene (nonché un enorme serie di anti-pattern che sembrano gran furbate sulle prime e risultano devastanti dopo due settimane)
Tali pattern, una volta condivisi hanno permesso di ridurre notevolmente la curva di apprendimento della metodologia.
Alla fine, in estrema sintesi, se il codice che usa il dominio non è "leggibile" dall'esperto, è sbagliato.
Uno degli aspetti che volevo mettere in evidenza è proprio questo. Avete sperimentato, e mi sembra che la conseguenza sia una consapevolezza più profonda di "Eric nel libro ha detto di non fare questa cosa".
Alla luce delle nostre sperimentazioni abbiamo anche compreso che il libro di Evans non è affatto "esaustivo" (sebbene FONDAMENTALE). Prendiamo ad esempio la mutabilità di un valueobject. Nel libro si _consiglia_ di renderli immutabili: noi un paio di volte abbiamo pensato che fosse sensato allontanarsi da questo consiglio, con effetti devastanti di lì ad un mese.
Su questo io sono abbastanza categorico. Un VO è immutabile. I casini vengono quando si deve gestire la persistenza con framework non troppo flessibili, quindi devi lasciare aperte certe backdoor...
Così come sulle referenze circolari fra entità (sconsigliate, ma non "vietate"), per fare esempi semplici che però hanno bruciato settimane di lavoro in refactoring. Oppure la centralità di boundary context ben definiti ed in dipendenti a priori (cosa ben spiegata nel libro, ma forse senza la sufficiente enfasi, quasi che sia più importante del concetto di entità/value object, direi).
Su questa parte in particolare Eric è "pentito" :-) Se riscrivesse il libro ora metterebbe all'inizio i Bounded Context ed il Context Mapping. Solo dopo i pattern di modellazione (e fra questi Aggregates sopra tutti).
Siamo giunti alla conclusione che ogni volta che la rappresentazione del dominio fatica ad adottare questi pattern (ed altri pattern casalinghi) c'è da qualche parte un errore di comprensione del modello di business stesso.
Direi che siete su un'ottima strada.
E nell'ultimo anno, quando questo succede, riprendiamo la discussione dall'inizio con il domain expert.
Questo semplicemente perché abbiamo osservato che è più economico!
Se lo dici così diretto, sembra che ci siamo messi d'accordo :-)
Sottoscrivo completamente: ad un certo punto capisci di non avere capito ed approfondisci, a costo di rifare pezzi già fatti. Perche ora sai che sono fatti su presupposti sbagliati.
E' chiaro che essendo pattern "casalinghi" non hanno l'autorevolezza di un libro stampato (e solo la produttività concreta che hanno dimostrato ha reso possibile la loro diffuzione nella nostra azienda).
Purtroppo, di questi tempi, con commerciali che vendono sistematicamente al ribasso, la tranquillità di sbagliare da noi non c'è.
Hai anche già indicato il problema. Se abbassi troppo gli spazi di manovra, di fatto stai ipotizzando il progetto in cui non puoi permetterti di sbagliare nulla. Ovvero una condizione perfetta per sbagliare e non poter correggere. Per certi versi simile alla partita dell'Inter di ieri sera.
Vero, il rischio di degradare in tale condizione esiste (ed è pure capitato in un progetto).
Tuttavia abbiamo imparato così bene l'importanza del modello dominio che su quello cerchiamo di non sbagliare.
E se ci accorgiamo di un errore potenziale, fermiamo tutto (con sommo terrore e grande disapprovazione dei commerciali) e riprendiamo l'analisi con l'esperto di dominio.
Questi pattern "stringenti" servono quasi da cartina tornasole: se fatichiamo ad adottarli, capiamo che abbiamo frainteso qualcosa del modello stesso e cerchiamo subito un deeper insight.
Per me è sostanzialmente lo stesso. In particolare con gli aggregati.
... ma la domanda ora è: "Dove siete stati tutto questo tempo?" :-)
E senza questi pattern, di fatto, molti colleghi avrebbero probabilmente rifiutato nei fatti la metodologia in toto.
... qui ti chiederei di espandere. Cosa avrebbero rifiutato, ed a favore di cosa?
Noi lavoriamo anche per l'industria e l'energia.
In questi ambiti, molto spesso le applicazioni che abbiamo sviluppato finora sono molto data driven. Ed in effetti tipicamente i nostri dba dettano quasi legge! :-D
Un mondo diverso è possibile...
Alcuni programmatori che si sono trasferiti lo scorso anno dal settore energia alla finanza hanno opposto una certa resistenza ad allontanarsi da un modello DB -> servizi SOA (procedurali) -> GUI sostanzialmente rad.
Solo la enorme complessità dei problemi che si sono trovati davanti (come gestire le sessioni di consulenza mifid per i private banker di una grande banca) li ha convinti che un approccio del genere non funzionava (in tempi e qualità compatibili con l'esigenze del cliente).
A volte basta aspettare sulla riva del fiume, come il cinese del proverbio.
Senza capacità di rispondere anche su aspetti tecnici (magari ragionando insieme a chi pone un problema, cercando insieme soluzioni generali), si perde credibilità personale (che purtroppo spesso nella pratica, viene identificata con la credibilità e la validità della metodologia stessa).
E' chiaro che la parte tecnica serve. Ma è anche vero che molto spesso gli aspetti vengono eccessivamente sovrapposti. Ricordo una discussione abbastanza accesa a Better Software l'anno scorso riguardo al fatto che il Coach dovesse dare anche una guida tecnica. Il ruolo del coach dovrebbe essere quello di far crescere il team, trovando i propri punti di forza. Essere ancheuna guida tecnica potrebbe essere una complicazione.
Però la risposta corretta è quella che suggerisci: ragionando insieme le soluzioni si trovano. E - per capirci - a me rispondere alle domande incasinate... piace. L'aspetto che mi inquieta a volte è la ricerca di "regole".
Personalmente sono molto più critico rispetto alle "regole" di processo che ai pattern di modellazione.
Fin ora tutti i tentativi di rendere più Agile i processi di sviluppo del settore finanza sono falliti miseramente (contrariamente a quanto avviene nel settore industria, per esempio).
Se è evidente a tutti che il valore sta nelle persone che lavorano nel team, la complessità dei problemi che affrontiamo (e forse anche la dimensione degli applicativi che stiamo vendendo di recente) sfugge alle metodologie tanto decantate da altri.
Il mondo bancario in effetti è particolarmente ingessato. Ho l'impressione che sia anche la conseguenza di un mercato sostanzialmente non competitivo, perché siamo in un settore in cui si potrebbe fare "immensamente meglio" ma in cui ho visto solo situazioni che andavano "un pochino meglio". Il discorso sarebbe lunghissimo, ma la sintesi è "troppa (inutile) politica".
Però ho l'impressione che tu abbia qualcosa di interessante e di specifico da dire anche in sede di processo. Oppure semplicemente mi hai incuriosito.
Noi ci siamo trovati ad essere una specie di scatola nera nell'aziende: in ogni iterazione buttano dentro specifiche di altissimo livello -> rompiamo le balle al domain expert fin quando basta -> diamo dei tempi -> rispettiamo i tempi -> il cliente è soddisfatto.
Quando il management ha cercato di risparmiare sull'analisi di dominio, tutte le volte abbiamo finito per rifare il lavoro (in un caso ben tre volte!).
Glielo avete fatto pesare con adeguato sarcasmo? ;-)
L'unico aspetto del processo che seguiamo sempre è l'assoluta priorità del dominio rispetto al resto (db, servizi, gui etc).
Fin quando non ci è _chiaro_ il dominio del problema non diamo nemmeno i tempi!
D'altronde che cos'è la responsabilità se non la capacità di rispondere?
Ok, come classifichi l'assunzione di responsabilità di uno che ti dice: "ho fatto come dice il libro?". Io ci vedo un po' il riflesso di un ambiente che non tollera facilmente gli errori. Ho l'impressione che stiamo dicendo cose simili da angolazioni differenti.
Mah.. ho la fortuna di lavorare in un azienda in cui abbiamo investito circa 20 mesi uomo per sviluppare un framework interno per sviluppare rapidamente GUI basate su domini fortemente tipizzati e molto complessi. Apparentemente follia pura!
A me torna parecchio, invece. Specialmente se siete specializzati su una fascia di mercato ben precisa. Nel piccolo mi sono trovato a spendere tempo sulla customizzazione del comportamento degli ORM per le gestione dei Value Objects, o sulla protezione dell'immutabilità.
Eppure è stata una decisione ben ponderata, perché i prodotti disponibili sul mercato non permettevano la produttività di cui avevamo bisogno.
Ho partecipato personalmente alla progettazione ed allo sviluppo di tale framework ed eravamo tutti coscienti (management incluso) dei rischi di tale percorso.
Non siamo mai stati "cazziati" per gli errori che abbiamo fatto (ed i conseguenti refactoring della codebase che abbiamo causato).
Ma credo sia il mercato a non tollerare certi errori. Ogni banca da cui andiamo ha dei processi mastodontici di approvazione degli applicativi!
Dal punto di vista "lean" mi viene da chiedere: "Qual è il valore aggiunto di questi processi?". Il problema è che ad essere sbagliati sono loro. E spesso non puoi risolvere un problema con gli stessi strumenti con cui il problema è stato creato. O (più pessimisticamente) con gli stessi uomini.
In realtà il mercato è dominato dagli errori, e dalle strategie tese a parsi il c***, non ad evitarli.
Ogni deploy è vissuto come "che bello, oggi andiamo al ministero"! E la concorrenza è spietata. Noi puntiamo all'eccellenza (da ben prima del mio arrivo in azienda), ma abbiamo dovuto fare i conti con una concorrenza basata sul prezzo (e sui tempi di consegna).
A volte quello che manca è la sicurezza di essere sulla buona strada. La tranquillità di poter dire: "Fate pure, fra 2 anni avrete una code base non mantenibile ed il nostro prezzo per fare la stessa cosa sarà il doppio, perché dovremo togliere il vecchio E rifarlo per bene".
Siamo tutti coscienti di essere stati molto fortunati ad uscirne vivi (e fortunatamente arzilli :-D).
Non è fortuna.
Devo dire comunque, che l'assenza di framework mainstream seriamente orientati al DDD e che non richiedano di essere combattuti, faciliterebbe.
...intendevi la presenza?
Sì, scusa. Tutto ciò che trovo in giro è ben lungi dalle nostre esigenze (in finanza).
Avete avuto modo di provare Naked Objects (ma è zona Java, se non vado errato)?
La maggioranza degli sviluppatori (me compreso) preferisce le strade battute. Personalmente tutte le volte che me ne discosto devo avere ottime ragioni per farlo.
...beh se ho un nuovo problema, la strada battuta è un po' difficile. Non è che si vada a caccia della soluzione esplorativa "a prescindere", se con i pattern classici la cosa "fila", bene. Se ho un problema relativamente nuovo e mi trovo in difficoltà con quello che ho implementato... provo una soluzione alternativa.
Alcune volte le strade battute sono sbagliate. Ti potrei fare un breve elenco di pattern battutissimi, ma che abbiamo dovuto abbiamo dovuto abbandonare a ragion veduta.
Un esempio sempre sconcertante quando condividiamo il nostro approccio con i colleghi del settore energia: l'event EventBroker è un (anti)pattern per disaccoppiare dagli eventi .NET. _Sul domain model_ è una soluzione ad un sintomo. Ma abbiamo compreso che genera più problemi di quanti non ne risolva.
Nelle ultime evoluzioni di DDD, Eric ha spinto notevolmente verso una comunicazione basata sui Domain Event, ma al suo livello sono estremamente disaccoppiati dall'infrastruttura tecnologica. Mi pare che tu stia parlando di una cosa differente. Ed in questo caso concordo con te in pieno: le soluzioni tecnologiche attirano i programmatori come le mosche, ma non spingono mai ad affrontare la complessità del problema. Anche perché i problemi veri si fa fatica a spiegarli in una demo.
Così abbiamo dovuto risalire al problema vero e risolverlo alla base.
Musica per le mie orecchie :-)
E quando capita, mi rendo conto di quanto giovane sia la nostra "attività artigiana".
Lo sviluppo software, checché ne dicano i grandi vendor è appena alla preistoria...
Questo decisamente, ma la crescita è veloce :-)
Non sono così d'accordo. Volendo fare un paragone con l'architettura classica, siamo ancora a Micene, intorno al 1400 A.C.
Non ho la più pallida idea di dove siamo. Quello che so è che pochi altri campi stanno manifestando una crescita ed una condivisione del sapere così rapida ed interconnessa. In altri settori i progressi sono lenti perché c'è poca condivisione. Quello che avviene nello sviluppo software (user groups, mailing list, conferenze, incontri, blogs tweets) ha pochi uguali in altri territori. Anche se pare che la comunità di chi fa la maglia ai ferri o all'uncinetto sia altrettanto organizzata (sembra una battuta, ma è la verità).
... ma la domanda ora è: "Dove siete stati tutto questo tempo?" :-)
A lavorare... :-D
Purtroppo abbiamo avuto un enorme sovraccarico di lavoro in questi anni. Poi c'è da dire che non è parte della nostra cultura aziendale mandare i dipendenti in giro a formarsi.
I nostri manager credono solo nella formazione sul campo, battendo il naso (e sui libri di cui disponiamo a bizzeffe, ma GUAI a dire "facciamo così perché lo dice Evans". Da noi le autoritas le possono citare SOLO gli statistici! :-D).
Noi lavoriamo anche per l'industria e l'energia.
In questi ambiti, molto spesso le applicazioni che abbiamo sviluppato finora sono molto data driven. Ed in effetti tipicamente i nostri dba dettano quasi legge! :-D
Un mondo diverso è possibile...
Attenzione che queste metodologie (data/db driven) in quei contesti sono assoluttamente perfetti! Una cosa che abbiamo imparato col sangue è che DDD non è sempre la scelta migliore economicamente parlando!
Il mondo bancario in effetti è particolarmente ingessato. Ho l'impressione che sia anche la conseguenza di un mercato sostanzialmente non competitivo, perché siamo in un settore in cui si potrebbe fare "immensamente meglio" ma in cui ho visto solo situazioni che andavano "un pochino meglio". Il discorso sarebbe lunghissimo, ma la sintesi è "troppa (inutile) politica".
Non saprei... ho incontrato fior di architetti software occupati ad affrontare problemi estremamente complessi in banca.
Gente così spessa da zittire guru inviati dalla Microsoft nel merito.
Oltre alla "politica", certa ingessatura è effettivamente dovuta alla complessità dei problemi da affrontare, che hanno a che fare più con il rapporto fra l'organico ed il software che con il software stesso o l'integrazione fra i software.
Però ho l'impressione che tu abbia qualcosa di interessante e di specifico da dire anche in sede di processo. Oppure semplicemente mi hai incuriosito.
Semplicemente, dopo aver osservato (e provato) diversi approcci agili (lean, scrum), ho capito che tali approcci funzionano in modo eccellente in contesti relativamente semplici (se comparati con gli applicativi che sviluppiamo noi).
Magari è la dimensione degli applicativi ad essere eccessiva: il nostro ultimo parto ha collezionato circa 15 anni uomo di sviluppo (ed alcuni moduli sono ancora in itinere), per 3 anni di elapsed (una decina di persone impiegate quasi a tempo pieno).
Per questo tipo di applicativi, le metodologie agili appaiono oggettivamente inadeguate (almeno nella nostra esperienza). Quella che più si avvicina a come lavoriamo (anche se non adottata in modo metodologico) è il feature driven development.
Noi ci siamo trovati ad essere una specie di scatola nera nell'aziende: in ogni iterazione buttano dentro specifiche di altissimo livello -> rompiamo le balle al domain expert fin quando basta -> diamo dei tempi -> rispettiamo i tempi -> il cliente è soddisfatto.
Quando il management ha cercato di risparmiare sull'analisi di dominio, tutte le volte abbiamo finito per rifare il lavoro (in un caso ben tre volte!).
Glielo avete fatto pesare con adeguato sarcasmo? ;-)
Non è stato necessario.
Siamo tutti professionisti capaci di imparare dai propri errori.
Dal punto di vista "lean" mi viene da chiedere: "Qual è il valore aggiunto di questi processi?". Il problema è che ad essere sbagliati sono loro. E spesso non puoi risolvere un problema con gli stessi strumenti con cui il problema è stato creato. O (più pessimisticamente) con gli stessi uomini.
In realtà il mercato è dominato dagli errori, e dalle strategie tese a parsi il c***, non ad evitarli.
Il paraculismo indubbiamente domina.
Ma non è solo quello.
Ci sono problematiche oggettive, legate al personale, alla distribuzione territoriale, alla storia aziendale etc...
Pensa cosa succede quando una banca è la fusione di 3, 4, 5 banche diverse.
Sistemi informativi diversi, standard documentativi diversi, processi che si fondono e si mescolano, personale da rieducare, migliaia di postazioni da gestire, personale con una enorme varietà di gradi di competenze informatiche (abbiamo visto utenti pagatissimi in crisi su dove infilare una chiavetta USB!)
Ogni deploy è vissuto come "che bello, oggi andiamo al ministero"!
E la concorrenza è spietata. Noi puntiamo all'eccellenza (da ben prima del mio arrivo in azienda), ma abbiamo dovuto fare i conti con una concorrenza basata sul prezzo (e sui tempi di consegna).
A volte quello che manca è la sicurezza di essere sulla buona strada. La tranquillità di poter dire: "Fate pure, fra 2 anni avrete una code base non mantenibile ed il nostro prezzo per fare la stessa cosa sarà il doppio, perché dovremo togliere il vecchio E rifarlo per bene".
Vero. Ma d'altronde chi conosce il futuro?
Siamo tutti coscienti di essere stati molto fortunati ad uscirne vivi (e fortunatamente arzilli :-D).
Non è fortuna.
Secondo me sì. Pensare che sia stata solo bravura sarebbe ridicolo.
Devo dire comunque, che l'assenza di framework mainstream seriamente orientati al DDD e che non richiedano di essere combattuti, faciliterebbe.
...intendevi la presenza?
Sì, scusa. Tutto ciò che trovo in giro è ben lungi dalle nostre esigenze (in finanza).
Avete avuto modo di provare Naked Objects (ma è zona Java, se non vado errato)?
Sì è Java. Visto, ma ancora insufficiente.
I nostri clienti ci chiedono GUI web veramente complesse (simili ad interfacce utente sviluppate negli anni e a cui i loro dipendenti sono abituati).
Un esempio sempre sconcertante quando condividiamo il nostro approccio con i colleghi del settore energia: l'event EventBroker è un (anti)pattern per disaccoppiare dagli eventi .NET. _Sul domain model_ è una soluzione ad un sintomo. Ma abbiamo compreso che genera più problemi di quanti non ne risolva.
Nelle ultime evoluzioni di DDD, Eric ha spinto notevolmente verso una comunicazione basata sui Domain Event, ma al suo livello sono estremamente disaccoppiati dall'infrastruttura tecnologica. Mi pare che tu stia parlando di una cosa differente. Ed in questo caso concordo con te in pieno: le soluzioni tecnologiche attirano i programmatori come le mosche, ma non spingono mai ad affrontare la complessità del problema. Anche perché i problemi veri si fa fatica a spiegarli in una demo.
Noi usiamo gli eventi .NET.
Questo è uno dei pattern casalinghi che adottiamo: ogni entità deve osservabile attraverso questo meccanismo. Il nome dell'evento deve esprimere cosa è successo ad un'entità, mentre l'event argument esprime come.
Non ci può essere alcun evento che sia slegato da un entità in un qualche boundary context.
E' stata una delle scelte più controverse della nostra infrastruttura/metodologia. Abbiamo dovuto affrontare una serie enorme di problematiche tecnologiche, ma alla fine questa scelta "idiomatica" ha pagato in termini di comprensibilità e riutilizzo del dominio.
Un paio di settimane fa a Portland (ME) si è svolto il DDDSummit, un piccolo raduno di "praticanti" di Domain Driven Design: per 3 giorni una decina di professionisti del settore si sono ritrovati per discutere cosa si intenda oggi per DDD, quale sia il valore e le prospettive e ...quant'altro potesse emergere dalla situazione "metto 10 teste nella stessa stanza e ne uscirà fuori qualcosa di buono" :-)
Ne è uscita un'immagine di DDD un po' diversa da quella che si può trarre da una lettura del libro. Il valore principale di DDD sta infatti nella formalizzazione di dominii complessi e/o inesplorati. In altre parole: Capire (con la C maiuscola) insieme al business quali sono i nodi specifici del dominio in cui andiamo ad operare. Pare scontato, ma non lo è affatto: molte aziende hanno un'idea piuttosto vaga di quale sia il loro reale core business, ed altre non hanno software in grado di garantire loro un vantaggio competitivo. I dominii non ancora consolidati sono l'area in cui DDD può fornire il massimo del valore, in quanto mix di processo/architettura/principi specializzato sull'esplorazione.
E il codice più mantenibile? Ed il disaccoppiamento sullo sviluppo in larga scala? Tutto ancora valido. Semplicemente, l'esperienza dei colleghi ha messo in luce che il primo e più importante risultato della Creative Collaboration, costruita attorno allo Ubiquitous Language è l'emersione di un modello di business chiaro anche ai ruoli business. Risultato che per molte aziende rappresenta un valore più grande e più immediato rispetto a quanto ottenibile ragionando "solo" in ottica di codice.
Viene per certi versi messo in second'ordine l'aspetto puramente architetturale. Di fatto siamo arrivati a parlare di "Supporting Architecture" includendo tra queste, sia il modello proposto nel "libro azzurro" sia l'architettura esagonale di Cockburn (con la quale ci sono notevoli punti in comune), sia le nuove tendenze quali CQRS ed Event Sourcing.
Un paio di settimane fa a Portland (ME) si è svolto il DDDSummit, un piccolo raduno di "praticanti" di Domain Driven Design: per 3 giorni una decina di professionisti del settore si sono ritrovati per discutere cosa si intenda oggi per DDD, quale sia il valore e le prospettive e ...quant'altro potesse emergere dalla situazione "metto 10 teste nella stessa stanza e ne uscirà fuori qualcosa di buono" :-)
Ne è uscita un'immagine di DDD un po' diversa da quella che si può trarre da una lettura del libro. Il valore principale di DDD sta infatti nella formalizzazione di dominii complessi e/o inesplorati. In altre parole: Capire (con la C maiuscola) insieme al business quali sono i nodi specifici del dominio in cui andiamo ad operare. Pare scontato, ma non lo è affatto: molte aziende hanno un'idea piuttosto vaga di quale sia il loro reale core business, ed altre non hanno software in grado di garantire loro un vantaggio competitivo. I dominii non ancora consolidati sono l'area in cui DDD può fornire il massimo del valore, in quanto mix di processo/architettura/principi specializzato sull'esplorazione.
E il codice più mantenibile? Ed il disaccoppiamento sullo sviluppo in larga scala? Tutto ancora valido. Semplicemente, l'esperienza dei colleghi ha messo in luce che il primo e più importante risultato della Creative Collaboration, costruita attorno allo Ubiquitous Language è l'emersione di un modello di business chiaro anche ai ruoli business. Risultato che per molte aziende rappresenta un valore più grande e più immediato rispetto a quanto ottenibile ragionando "solo" in ottica di codice.
Viene per certi versi messo in second'ordine l'aspetto puramente architetturale. Di fatto siamo arrivati a parlare di "Supporting Architecture" includendo tra queste, sia il modello proposto nel "libro azzurro" sia l'architettura esagonale di Cockburn (con la quale ci sono notevoli punti in comune), sia le nuove tendenze quali CQRS ed Event Sourcing.
Ciao, io ho notato che in alcuni contesti (come l'adeguatezza ai profili MIFID e le consulenze di investimento) il nostro dominio inizia ad incapsulare un know how enorme, maggiore di quello che i nostri clienti hanno "coscientemente".
Alla terza banca, abbiamo notato che eravamo in grado di obbiettare nel merito agli esperti funzionali basandoci sulla (preziosissima) documentazione del dominio!
In effetti sembra che questa modellazione ordinata e ben organizzata ci faccia scegliere rispetto ai competitor (il cliente ha l'impressione che ne sappiamo più dei suoi consulenti, anche se questo ha ovvie conseguenze diplomatiche ;-)
In realtà, dopo ogni riunione noi torniamo semplicemente a guardare il codice del dominio e gli unit tests e poniamo domande su ciò che non ci torna. Questo fa emergere in fase di analisi i problemi e ci ha fatto risparmiare un fracco di tempo.
Tuttavia non sottovaluterei il valore del codice di dominio, stabile ed altamente testato (vantiamo 100% di coverage sui contesti più strategici, più qualche anno di produzione). Non solo la sua funzione documentativa è importante, dal nostro punto di vista aziendale di software house, quei 3 context che rivendiamo come sono hanno ampiamente ripagato il sangue che abbiamo buttato a scriverli!
Questi assembly rappresentano la sintesi migliore che abbiamo trovato fra la visione "a prodotto" del nostro capo e quella "a progetto" dei commerciali, che all'inizio erano terrorizzati e tremavano quando dicevamo "bisogna analizzare il dominio per dare dei tempi".
Un paio di settimane fa a Portland (ME) si è svolto il DDDSummit, un piccolo raduno di "praticanti" di Domain Driven Design: per 3 giorni una decina di professionisti del settore si sono ritrovati per discutere cosa si intenda oggi per DDD, quale sia il valore e le prospettive e ...quant'altro potesse emergere dalla situazione "metto 10 teste nella stessa stanza e ne uscirà fuori qualcosa di buono" :-)
Ne è uscita un'immagine di DDD un po' diversa da quella che si può trarre da una lettura del libro. Il valore principale di DDD sta infatti nella formalizzazione di dominii complessi e/o inesplorati. In altre parole: Capire (con la C maiuscola) insieme al business quali sono i nodi specifici del dominio in cui andiamo ad operare. Pare scontato, ma non lo è affatto: molte aziende hanno un'idea piuttosto vaga di quale sia il loro reale core business, ed altre non hanno software in grado di garantire loro un vantaggio competitivo. I dominii non ancora consolidati sono l'area in cui DDD può fornire il massimo del valore, in quanto mix di processo/architettura/principi specializzato sull'esplorazione.
E il codice più mantenibile? Ed il disaccoppiamento sullo sviluppo in larga scala? Tutto ancora valido. Semplicemente, l'esperienza dei colleghi ha messo in luce che il primo e più importante risultato della Creative Collaboration, costruita attorno allo Ubiquitous Language è l'emersione di un modello di business chiaro anche ai ruoli business. Risultato che per molte aziende rappresenta un valore più grande e più immediato rispetto a quanto ottenibile ragionando "solo" in ottica di codice.
Viene per certi versi messo in second'ordine l'aspetto puramente architetturale. Di fatto siamo arrivati a parlare di "Supporting Architecture" includendo tra queste, sia il modello proposto nel "libro azzurro" sia l'architettura esagonale di Cockburn (con la quale ci sono notevoli punti in comune), sia le nuove tendenze quali CQRS ed Event Sourcing.
sta procedendo a ritmo serrato la preparazione del DDD Day, il primo evento italiano interamente dedicato a Domain Driven Design. Si terrà a Bologna l'8 Ottobre 2011.
Credo che a molti dei partecipanti alla mailing list la cosa possa interessare, sia come partecipanti che come potenziali speakers.
La situazione dal punto di vista della Call For Papers, e dal punto di vista dell'organizzazione degli spazi, è ancora fluida dovrebbero esserci 2 track con qualche spazio open, nonché un ospite straniero di grido :-)
Ciao a tutti,
mi chiamo Uberto e lavoro come SW arch/team leader in una grossa telco a
Dusseldorf (quella rossa :)).
Colpevolvemente non sapevo dell'esistenza di questa ML, grazie ZioBrando! :)
Vengo rapidamente al punto. Essendo appassionato di buon codice avevo letto DDD
la prima volta nel 2005, l'ho riletto appena arrivato qui in Germania nel 2007 e
lo sto rileggendo oggi per la terza volta.
Nel frattempo il mio modo di scrivere codice si e' molto evoluto, sia per
l'esperienza vissuta qui (2 grossi progetti Java) sia per libri che ho letto, in
particolare GOOS e linguaggi che ho imparato Haskell e Lisp in primis.
Mi sono accorto che diverse cose che "ho imparato" recentemente erano gia'
descritte li' dettagliatamente (funzioni senza sideeffect, value object
immutabili) ma non me ne ero accorto la prima volta che l'avevo letto.
Riguardo alla sua distinzione tra ValueObject, Entity, Service invece
recentemente mi sono reso conto che uso sempre meno Entities e sempre piu'
Services.
Soprattutto non uso piu' Entities per mappare oggetti del dominio (Customer) ma
piuttosto stati tecnici (Controller, Cache, ConnectionPool).
Per il manipolare il dominio invece uso degli "Agent" (CustomerPersister,
CustomerRenderer) che in pratica non sono altro che classi che offrono uno o
piu' Service (di solito uno comunque). Gli Agent non hanno uno stato interno,
quindi non importa a quale Agent chiedo quale Service, la risposta dipende
chiaramente dallo stato del sistema in generale ma non dalla storia del singolo
agent. Se gli Agent serve usano Entity per interrogare lo stato generale del
sistema.
Se serve posso postare un po' di nostro codice "offuscato".
Da un punto di vista tecnico nessuno conosce la classe degli Agent e delle
Entity ma solo la loro interfaccia, che non espone nulla di stati interni o
parziali.
Perche' facciamo questo? Beh la risposta breve e' che questo meta-design ci
permette di aumentare considerevolmente la produttivita' mantenendo il codice
leggibile e completamente testato. Trattandosi di progetti di diverse kloc sono
discretamente fiero che non siano ancora legacy ma vivi e reattivi. :)
Mi chiedevo se nel mondo DDD c'e' qualcunaltro che si sta muovendo in questa
direzione.
Che ripeto non e' una cosa che ho cercato ma e' un qualcosa che mi sta venendo
fuori "da solo" dal TDD. :)
ciao
Uberto
ps. ho presentato uno dei nostri progetti e come usiamo gwt qui:
http://www.slideshare.net/ubertobarbini/develop-gwt-application-in-tdd
devo confessare che io invece non sono ancora riuscito a completare il GOOS. L'approccio di Freeman e Pryce mi piace un sacco, e ci sono un sacco di cose che tornano, ...ma non posso ancora dirmi completamente GOOSiano.
Quanto agli aspetti delle side effect free functions e dei Value Object, confermo che ci sono un sacco di punti di contatto: l'effetto che sto sperimentando su di me è che anche i test unitari (l'altra strada che sto battendo al momento è quella di BDD-Cucumber) tendono a migliorare notevolmente la loro leggibilità.
L'effetto che mi stai descrivendo mi rammenta qualcosa di cui parlò Matteo Vaccari all'ultima Codemotion, dove in effetti faceva a meno delle entity. Se testi per "fare" qualcosa, la maggior parte dei dati ...non serve. E' solo trasferimento di informazione. Dal punto di vista del comportamento è quasi irrilevante.
Io in questo momento sto seguendo un percorso diverso ma probabilmente con qualche analogia di fondo:
- forte disaccoppiamento degli aggregati
- comunicazione ad eventi tra gli aggregati
La Entity nel mio aggregato, raramente nasce dai dati. A volte li aggiungo alla fine. Per me è sostanzialmente una macchina a stati ed un contenitore di invarianti. Non so se il mio approccio di Entity come macchina a stati (non sempre ...spesso) torna con il tuo, ma ho l'impressione che stiamo vedendo qualcosa di simile.
.A questa cosa aggiungo il recente tentativo di applicare il paradigma alla Greg Young di testare con qualcosa di simile a
Given [events]*
When [command]
Then [event]
in un contesto di questo genere, il mio aggregato finisce per diventare un cosino molto molto semplice, con l'unico aggravio di complicazione di dover gestire un set di eventi in ingresso che arrivano su canali asincroni. Non banale all'inizio, ma dal punto di vista concettuale è piuttosto interessante. Ed i componenti sono "pluggabili" in maniera molto più elegante.
Tornando allo specifico della tua domanda, non so se ci sia un ruolo esplicito per gli Agent che citi. Ho classi che fanno, a volte sono locali all'aggregato, a volte sono comuni ed allora li promuovo a Service. Ma in generale la presenza di molti Service ...a me spesso puzza come uno smell di un modello anemico nascosto da qualche parte.
No sembra essere il tuo caso, però.
E' anche vero che se hai una componente del dominio senza troppa complessità, l'anagrafe clienti ad esempio, ...non ti metti a farci DDD sopra. Buona parte delle Entity che vedo in giro sono "ho cominciato DDD da qui perché questa è la prima cosa che ho capito dal libro"...
Brando
Il giorno 09 agosto 2011 14:34, ubertob <uberto@...> ha scritto:
Ciao a tutti,
mi chiamo Uberto e lavoro come SW arch/team leader in una grossa telco a Dusseldorf (quella rossa :)).
Colpevolvemente non sapevo dell'esistenza di questa ML, grazie ZioBrando! :)
Vengo rapidamente al punto. Essendo appassionato di buon codice avevo letto DDD la prima volta nel 2005, l'ho riletto appena arrivato qui in Germania nel 2007 e lo sto rileggendo oggi per la terza volta.
Nel frattempo il mio modo di scrivere codice si e' molto evoluto, sia per l'esperienza vissuta qui (2 grossi progetti Java) sia per libri che ho letto, in particolare GOOS e linguaggi che ho imparato Haskell e Lisp in primis.
Mi sono accorto che diverse cose che "ho imparato" recentemente erano gia' descritte li' dettagliatamente (funzioni senza sideeffect, value object immutabili) ma non me ne ero accorto la prima volta che l'avevo letto.
Riguardo alla sua distinzione tra ValueObject, Entity, Service invece recentemente mi sono reso conto che uso sempre meno Entities e sempre piu' Services.
Soprattutto non uso piu' Entities per mappare oggetti del dominio (Customer) ma piuttosto stati tecnici (Controller, Cache, ConnectionPool).
Per il manipolare il dominio invece uso degli "Agent" (CustomerPersister, CustomerRenderer) che in pratica non sono altro che classi che offrono uno o piu' Service (di solito uno comunque). Gli Agent non hanno uno stato interno, quindi non importa a quale Agent chiedo quale Service, la risposta dipende chiaramente dallo stato del sistema in generale ma non dalla storia del singolo agent. Se gli Agent serve usano Entity per interrogare lo stato generale del sistema.
Se serve posso postare un po' di nostro codice "offuscato".
Da un punto di vista tecnico nessuno conosce la classe degli Agent e delle Entity ma solo la loro interfaccia, che non espone nulla di stati interni o parziali.
Perche' facciamo questo? Beh la risposta breve e' che questo meta-design ci permette di aumentare considerevolmente la produttivita' mantenendo il codice leggibile e completamente testato. Trattandosi di progetti di diverse kloc sono discretamente fiero che non siano ancora legacy ma vivi e reattivi. :)
Mi chiedevo se nel mondo DDD c'e' qualcunaltro che si sta muovendo in questa direzione.
Che ripeto non e' una cosa che ho cercato ma e' un qualcosa che mi sta venendo fuori "da solo" dal TDD. :)
in realtá c'é qualche altro punto di contatto interessante.
Se ragioni in termini di Eventi, il contenuto informativo, i "dati" per intenderci. Stanno sostanzialmente negli eventi. Gli aggregati gestiscono le transizioni di stato in risposta agli eventi, ma le transizioni di stato dentro in confini dell'aggregato le gestisci come ti pare...salvo buttare fuori un evento al termine della trasformazione.
C'é un pezzo di ES/CQRS che non ho avuto modo di approfondire, che probabilmente ha punti in comune con quello che stai vedendo te. Penso soprattutto al tuo CustomerRenderer. La trasformazione dai dati in ingresso (comandi o eventi) ai dati in uscita View é gestita in maniera asincrona, spesso prepopolando tabelle o viste che poi vengono sparate "secche" in presentation senza passare dal Domain Model. Ho l'impressione che quello che avviene lí non sia molto diverso da quello che avviene nel tuo renderer. Cambia il momento in cui viene invocato, peró.
Per quanto riguarda i persister, io é da un po' che ho ricominciato a ragionare senza persistenza. Mi faccio i repository, ma in realtá li mocko. Alla fine non c'é molto. E posso decidere abbastanza tardi se andare su SQL o noSQL, etc.
devo confessare che io invece non sono ancora riuscito a completare il GOOS. L'approccio di Freeman e Pryce mi piace un sacco, e ci sono un sacco di cose che tornano, ...ma non posso ancora dirmi completamente GOOSiano.
Quanto agli aspetti delle side effect free functions e dei Value Object, confermo che ci sono un sacco di punti di contatto: l'effetto che sto sperimentando su di me è che anche i test unitari (l'altra strada che sto battendo al momento è quella di BDD-Cucumber) tendono a migliorare notevolmente la loro leggibilità.
L'effetto che mi stai descrivendo mi rammenta qualcosa di cui parlò Matteo Vaccari all'ultima Codemotion, dove in effetti faceva a meno delle entity. Se testi per "fare" qualcosa, la maggior parte dei dati ...non serve. E' solo trasferimento di informazione. Dal punto di vista del comportamento è quasi irrilevante.
Io in questo momento sto seguendo un percorso diverso ma probabilmente con qualche analogia di fondo:
- forte disaccoppiamento degli aggregati
- comunicazione ad eventi tra gli aggregati
La Entity nel mio aggregato, raramente nasce dai dati. A volte li aggiungo alla fine. Per me è sostanzialmente una macchina a stati ed un contenitore di invarianti. Non so se il mio approccio di Entity come macchina a stati (non sempre ...spesso) torna con il tuo, ma ho l'impressione che stiamo vedendo qualcosa di simile.
.A questa cosa aggiungo il recente tentativo di applicare il paradigma alla Greg Young di testare con qualcosa di simile a
Given [events]*
When [command]
Then [event]
in un contesto di questo genere, il mio aggregato finisce per diventare un cosino molto molto semplice, con l'unico aggravio di complicazione di dover gestire un set di eventi in ingresso che arrivano su canali asincroni. Non banale all'inizio, ma dal punto di vista concettuale è piuttosto interessante. Ed i componenti sono "pluggabili" in maniera molto più elegante.
Tornando allo specifico della tua domanda, non so se ci sia un ruolo esplicito per gli Agent che citi. Ho classi che fanno, a volte sono locali all'aggregato, a volte sono comuni ed allora li promuovo a Service. Ma in generale la presenza di molti Service ...a me spesso puzza come uno smell di un modello anemico nascosto da qualche parte.
No sembra essere il tuo caso, però.
E' anche vero che se hai una componente del dominio senza troppa complessità, l'anagrafe clienti ad esempio, ...non ti metti a farci DDD sopra. Buona parte delle Entity che vedo in giro sono "ho cominciato DDD da qui perché questa è la prima cosa che ho capito dal libro"...
Brando
Il giorno 09 agosto 2011 14:34, ubertob <uberto@...> ha scritto:
Ciao a tutti,
mi chiamo Uberto e lavoro come SW arch/team leader in una grossa telco a Dusseldorf (quella rossa :)). Colpevolvemente non sapevo dell'esistenza di questa ML, grazie ZioBrando! :)
Vengo rapidamente al punto. Essendo appassionato di buon codice avevo letto DDD la prima volta nel 2005, l'ho riletto appena arrivato qui in Germania nel 2007 e lo sto rileggendo oggi per la terza volta.
Nel frattempo il mio modo di scrivere codice si e' molto evoluto, sia per l'esperienza vissuta qui (2 grossi progetti Java) sia per libri che ho letto, in particolare GOOS e linguaggi che ho imparato Haskell e Lisp in primis.
Mi sono accorto che diverse cose che "ho imparato" recentemente erano gia' descritte li' dettagliatamente (funzioni senza sideeffect, value object immutabili) ma non me ne ero accorto la prima volta che l'avevo letto.
Riguardo alla sua distinzione tra ValueObject, Entity, Service invece recentemente mi sono reso conto che uso sempre meno Entities e sempre piu' Services. Soprattutto non uso piu' Entities per mappare oggetti del dominio (Customer) ma piuttosto stati tecnici (Controller, Cache, ConnectionPool).
Per il manipolare il dominio invece uso degli "Agent" (CustomerPersister, CustomerRenderer) che in pratica non sono altro che classi che offrono uno o piu' Service (di solito uno comunque). Gli Agent non hanno uno stato interno, quindi non importa a quale Agent chiedo quale Service, la risposta dipende chiaramente dallo stato del sistema in generale ma non dalla storia del singolo agent. Se gli Agent serve usano Entity per interrogare lo stato generale del sistema.
Se serve posso postare un po' di nostro codice "offuscato".
Da un punto di vista tecnico nessuno conosce la classe degli Agent e delle Entity ma solo la loro interfaccia, che non espone nulla di stati interni o parziali.
Perche' facciamo questo? Beh la risposta breve e' che questo meta-design ci permette di aumentare considerevolmente la produttivita' mantenendo il codice leggibile e completamente testato. Trattandosi di progetti di diverse kloc sono discretamente fiero che non siano ancora legacy ma vivi e reattivi. :)
Mi chiedevo se nel mondo DDD c'e' qualcunaltro che si sta muovendo in questa direzione. Che ripeto non e' una cosa che ho cercato ma e' un qualcosa che mi sta venendo fuori "da solo" dal TDD. :)
devo confessare che io invece non sono ancora riuscito a completare il GOOS. L'approccio di Freeman e Pryce mi piace un sacco, e ci sono un sacco di cose che tornano, ...ma non posso ancora dirmi completamente GOOSiano.
:) In goos ci sono moltissime "perle" ma il concetto nuovo di fondo e' fare TDD usando interfacce e mock. Il risultato e' praticamente BDD, i tuoi test si chiamano shouldBlabla dove blabla e' una "storia" e piu' che testare lo stato con assert vari testi le iterazioni tra l'oggetto "tra i morsetti" e i vari mock.
Io ne sono entusiasta, soprattutto per come funziona Java. Alcuni colleghi invece si lamentano che (testuali parole) "ma tu dai i dati che vuoi tu al tuo oggetto e testi che esca quello che vuoi tu... in pratica non testi nulla".
Il punto e' che testi il design e testi ogni singola classe indipendentemente, e' vero che esiste il rischio di misalignment tra test, tipo che testo che la classe A mandi 1 alla classe B ma sui test della classe B testo che A mi mandi 2.
Pero' proprio stare attenti a questi problemi fa si che il design sia ultra solido IMHO.
Quanto agli aspetti delle side effect free functions e dei Value Object, confermo che ci sono un sacco di punti di contatto: l'effetto che sto sperimentando su di me è che anche i test unitari (l'altra strada che sto battendo al momento è quella di BDD-Cucumber) tendono a migliorare notevolmente la loro leggibilità.
si assolutamente. Io ho usato cucumber per test di accettazione, e mi piace molto. I miei test JUnit sono sempre piu' simili a gherkin.
L'effetto che mi stai descrivendo mi rammenta qualcosa di cui parlò Matteo Vaccari all'ultima Codemotion, dove in effetti faceva a meno delle entity. Se testi per "fare" qualcosa, la maggior parte dei dati ...non serve. E' solo trasferimento di informazione. Dal punto di vista del comportamento è quasi irrilevante.
Con Matteo ci sentiamo spesso e siamo abbastanza allineati. Qualche volta pero' le Entity servono, per esempio se hai un controller di una UI devi testare che gli stati interni funzionino.
Non ho trovato pero' esempi di oggetti di dominio che avessero bisogno di stati interni. Usando oggetti immutabili, funzioni statiche pure per gli algoritmi e agenti per scambiare messaggi sono riuscito finora a rappresentare tutto il dominio.
Io in questo momento sto seguendo un percorso diverso ma probabilmente con qualche analogia di fondo:
- forte disaccoppiamento degli aggregati
- comunicazione ad eventi tra gli aggregati
La Entity nel mio aggregato, raramente nasce dai dati. A volte li aggiungo alla fine. Per me è sostanzialmente una macchina a stati ed un contenitore di invarianti. Non so se il mio approccio di Entity come macchina a stati (non sempre ...spesso) torna con il tuo, ma ho l'impressione che stiamo vedendo qualcosa di simile.
Si anche per me le entity sono macchine a stati e le testo come tali. Ultimamente mi sono anche rispolverato la differenza tra stato inteso come m-configuration e stato inteso come "world". Le entities lavorano solo sul primo, gli agent sul secondo.
.A questa cosa aggiungo il recente tentativo di applicare il paradigma alla Greg Young di testare con qualcosa di simile a
Given [events]*
When [command]
Then [event]
in un contesto di questo genere, il mio aggregato finisce per diventare un cosino molto molto semplice, con l'unico aggravio di complicazione di dover gestire un set di eventi in ingresso che arrivano su canali asincroni. Non banale all'inizio, ma dal punto di vista concettuale è piuttosto interessante. Ed i componenti sono "pluggabili" in maniera molto più elegante.
bello! in piccolo (messaggi sincroni) e' quello che facciamo in Goos, gli oggetti dialogano tra di loro scambiandosi value immutabili o primitivi. con eventi asincroni e' ovviamente piu' complicato.
Tornando allo specifico della tua domanda, non so se ci sia un ruolo esplicito per gli Agent che citi. Ho classi che fanno, a volte sono locali all'aggregato, a volte sono comuni ed allora li promuovo a Service. Ma in generale la presenza di molti Service ...a me spesso puzza come uno smell di un modello anemico nascosto da qualche parte.
No sembra essere il tuo caso, però.
In effetti c'e' un pericolo... in teoria gli Agents dovrebbero essere "lavoratori". Per esempio CustomerArchiver (il nome dell'interfaccia e' sempre un oggetto+un verbo soggettivato) XmlReader, InvoiceCalculator ecc.
Pero' ho visto che e' facile finire con "agent generici" tipo CustomerManager che non hanno piu' alcuna attinenza col dominio ma semplicemente "fanno qualcosa su qualcosaltro", oppure mescolare i layer (noi usiamo PortAndAdapter di Cockburn come riferimento) e mettere un agent che parli direttamente http o legga dal fs.
Su questo occorre stare attenti, ma non direi piu' che con altri modi di design.
E' anche vero che se hai una componente del dominio senza troppa complessità, l'anagrafe clienti ad esempio, ...non ti metti a farci DDD sopra. Buona parte delle Entity che vedo in giro sono "ho cominciato DDD da qui perché questa è la prima cosa che ho capito dal libro"...
:)) Di fondo la genialita' di DDD e' stata quella di rimettere il dominio al centro della programmazione, e' una di quelle cose che una volta letta non mi e' piu' uscita di testa. Purtroppo in Java altri punti di vista sono diventati mainstream o forse dovrei dire m@inBean :)
Non mi è molto chiaro in che modo usiate le entità per mappare stati tecnici.
Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio condiviso fra esperti di dominio e sviluppatori: magari il vostro applicativo gestisce oggetti virtuali, come cache o application pool e tutto tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per stati tecnici.
Anche io ho imparato (da Haskell, più che da Evans) il valore dell'immutabilità, però molte entità continuo a vedermele mutabili, anche se solo per un singolo field.
Inoltre, quando modello, mi preoccupo che un qualunque collega che non sa niente del contesto in esame e non abbia partecipato alle riunioni con l'esperto del dominio, leggendo le interfacce e la documentazione del codice capisca come funziona il dominio e come si usa (possibilmente senza andare a guardare gli unit tests, a cui comunque anche noi diamo molto peso, cercando di raggiungere almeno il 100% di coverage).
Come effetto però noi abbiamo una fortissima tipizzazione e gerarchie di oggetti molto basse: all'inizio tutte le entità derivavano da uno storico IBusinessObject, ma per fortuna con sangue sudore e lacrime ce ne siamo ormai liberati per il 95% negli applicativi sviluppati in DDD. Questo ci permette di non violare il Liskow principle (e la definizione di contesti molto ben definiti ci permette di ridurre i rischi di violare l'OCP e il SRP).
Il riuso del dominio avviene solo quando due clienti ci vedono un aspetto del loro processo/business nello stesso modo (il che succede tanto più di frequente quanto più precisi siamo stati nel definire i contesti di ciascun assembly di dominio).
Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il business effettivo che le nostre classi modellavano). Agent mi sembra sull'estremo opposto, mi sembra incapsulare il solo comportamento di business, ma senza linea di continuita (ovvero senza identità/entità) e senza stato (non so se mi spiego).
Non conosco GOOS (mai sentito!!! :-O !!!), ma anche noi usiamo molto i mocks sia per testare il dominio che ciò che ne dipende (in particolare i presenter, ma anche gli script di importazione dati per esempio) ed abbiamo adottato da circa un anno una convenzione di naming degli unit test che descrivevo qui (in realtà, alcuni miei colleghi già la adottavano da prima... io sono sempre l'ultimo a sapere le cose! :-D).
A presto!
Giacomo
PS: Una considerazione importante: IBusinessObject si rivela distruttivo quando ci SERVE che gli sviluppatori parlino la stessa lingua degli esperti di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core business del cliente (e il cliente, del suo core business, ne sa :-D).
Al constrario, quando il cliente parla in termini di tabelle e trigger (cosa che ci succede talvolta in industria ed energia) o quando gli applicativi sviluppati si occupano sostanzialmente di analisi dati (molti nostri applicativi sono tool di data mining e business intelligence avanzata, ci chiamiamo Operational Research System non a caso), diventa veramente utile e produttivo.
E' possibile che voi vi troviate in una situazione simile, sebbene simmetricamente opposta?
devo confessare che io invece non sono ancora riuscito a completare il GOOS. L'approccio di Freeman e Pryce mi piace un sacco, e ci sono un sacco di cose che tornano, ...ma non posso ancora dirmi completamente GOOSiano.
:) In goos ci sono moltissime "perle" ma il concetto nuovo di fondo e' fare TDD usando interfacce e mock. Il risultato e' praticamente BDD, i tuoi test si chiamano shouldBlabla dove blabla e' una "storia" e piu' che testare lo stato con assert vari testi le iterazioni tra l'oggetto "tra i morsetti" e i vari mock.
Io ne sono entusiasta, soprattutto per come funziona Java. Alcuni colleghi invece si lamentano che (testuali parole) "ma tu dai i dati che vuoi tu al tuo oggetto e testi che esca quello che vuoi tu... in pratica non testi nulla".
Il punto e' che testi il design e testi ogni singola classe indipendentemente, e' vero che esiste il rischio di misalignment tra test, tipo che testo che la classe A mandi 1 alla classe B ma sui test della classe B testo che A mi mandi 2.
Pero' proprio stare attenti a questi problemi fa si che il design sia ultra solido IMHO.
Quanto agli aspetti delle side effect free functions e dei Value Object, confermo che ci sono un sacco di punti di contatto: l'effetto che sto sperimentando su di me è che anche i test unitari (l'altra strada che sto battendo al momento è quella di BDD-Cucumber) tendono a migliorare notevolmente la loro leggibilità.
si assolutamente. Io ho usato cucumber per test di accettazione, e mi piace molto. I miei test JUnit sono sempre piu' simili a gherkin.
L'effetto che mi stai descrivendo mi rammenta qualcosa di cui parlò Matteo Vaccari all'ultima Codemotion, dove in effetti faceva a meno delle entity. Se testi per "fare" qualcosa, la maggior parte dei dati ...non serve. E' solo trasferimento di informazione. Dal punto di vista del comportamento è quasi irrilevante.
Con Matteo ci sentiamo spesso e siamo abbastanza allineati. Qualche volta pero' le Entity servono, per esempio se hai un controller di una UI devi testare che gli stati interni funzionino.
Non ho trovato pero' esempi di oggetti di dominio che avessero bisogno di stati interni. Usando oggetti immutabili, funzioni statiche pure per gli algoritmi e agenti per scambiare messaggi sono riuscito finora a rappresentare tutto il dominio.
Io in questo momento sto seguendo un percorso diverso ma probabilmente con qualche analogia di fondo:
- forte disaccoppiamento degli aggregati
- comunicazione ad eventi tra gli aggregati
La Entity nel mio aggregato, raramente nasce dai dati. A volte li aggiungo alla fine. Per me è sostanzialmente una macchina a stati ed un contenitore di invarianti. Non so se il mio approccio di Entity come macchina a stati (non sempre ...spesso) torna con il tuo, ma ho l'impressione che stiamo vedendo qualcosa di simile.
Si anche per me le entity sono macchine a stati e le testo come tali. Ultimamente mi sono anche rispolverato la differenza tra stato inteso come m-configuration e stato inteso come "world". Le entities lavorano solo sul primo, gli agent sul secondo.
.A questa cosa aggiungo il recente tentativo di applicare il paradigma alla Greg Young di testare con qualcosa di simile a
Given [events]*
When [command]
Then [event]
in un contesto di questo genere, il mio aggregato finisce per diventare un cosino molto molto semplice, con l'unico aggravio di complicazione di dover gestire un set di eventi in ingresso che arrivano su canali asincroni. Non banale all'inizio, ma dal punto di vista concettuale è piuttosto interessante. Ed i componenti sono "pluggabili" in maniera molto più elegante.
bello! in piccolo (messaggi sincroni) e' quello che facciamo in Goos, gli oggetti dialogano tra di loro scambiandosi value immutabili o primitivi. con eventi asincroni e' ovviamente piu' complicato.
Tornando allo specifico della tua domanda, non so se ci sia un ruolo esplicito per gli Agent che citi. Ho classi che fanno, a volte sono locali all'aggregato, a volte sono comuni ed allora li promuovo a Service. Ma in generale la presenza di molti Service ...a me spesso puzza come uno smell di un modello anemico nascosto da qualche parte.
No sembra essere il tuo caso, però.
In effetti c'e' un pericolo... in teoria gli Agents dovrebbero essere "lavoratori". Per esempio CustomerArchiver (il nome dell'interfaccia e' sempre un oggetto+un verbo soggettivato) XmlReader, InvoiceCalculator ecc.
Pero' ho visto che e' facile finire con "agent generici" tipo CustomerManager che non hanno piu' alcuna attinenza col dominio ma semplicemente "fanno qualcosa su qualcosaltro", oppure mescolare i layer (noi usiamo PortAndAdapter di Cockburn come riferimento) e mettere un agent che parli direttamente http o legga dal fs.
Su questo occorre stare attenti, ma non direi piu' che con altri modi di design.
E' anche vero che se hai una componente del dominio senza troppa complessità, l'anagrafe clienti ad esempio, ...non ti metti a farci DDD sopra. Buona parte delle Entity che vedo in giro sono "ho cominciato DDD da qui perché questa è la prima cosa che ho capito dal libro"...
:)) Di fondo la genialita' di DDD e' stata quella di rimettere il dominio al centro della programmazione, e' una di quelle cose che una volta letta non mi e' piu' uscita di testa. Purtroppo in Java altri punti di vista sono diventati mainstream o forse dovrei dire m@inBean :)
Ciao a tutti, Il metodo che riporta alberto, suggerito da greg young, ovvero far comunicare gli aggregate root tramite eventi (asincroni) è una FIGATA PAZZESCA :-)
In CodicePlastico lo stiamo utilizzando su un progetto "finanziario" piuttosto complesso e ci ha permesso di gestire la complessità e le evoluzioni in modo veramente semplice ed efficacie. Facendo dialogare i vari aggregate tramite eventi si ha la garanzia di tenere tutto fortemente disaccoppiato e enfatizzare uno dei paradigmi dell'OOD: l'incapsulamento. Non è più necessario esporre i dati, ma tutto rimane interno agli aggregate che espongono solo metodi per le transizioni di stato. Anche i test diventano più semplici da scrivere e soprattutto manutenere e non impattano più direttamente sull'aggregate, ma verificano che l'aggregate, a fronte di un metodo, veicoli le giuste informazioni attraverso un opportuno evento.
In una visione più ampia, ci sono poi dei listener al di fuori del dominio che, in ascolto su questi eventi, si occupano di denormalizzare le informazioni e predisporle per le view in modo che siano facilmente consumabili dal presentation layer senza troppe (nessuna) trasformazioni.
Su questo fronte ci stiamo ancora facendo le ossa per definire il giusto equilibrio: table-per-view o un po' di normalizzazione e join in lettura?
Ciao melkio
Il giorno martedì 9 agosto 2011, Giacomo Tesio <giacomo@...> ha scritto:
> > > Ciao Uberto! > > Non mi è molto chiaro in che modo usiate le entità per mappare stati tecnici. > Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio condiviso fra esperti di dominio e sviluppatori: magari il vostro applicativo gestisce oggetti virtuali, come cache o application pool e tutto tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per stati tecnici.
> Anche io ho imparato (da Haskell, più che da Evans) il valore dell'immutabilità, però molte entità continuo a vedermele mutabili, anche se solo per un singolo field <http://epic.tesio.it/doc/single_mutable_state.html>.
> Inoltre, quando modello, mi preoccupo che un qualunque collega che non sa niente del contesto in esame e non abbia partecipato alle riunioni con l'esperto del dominio, leggendo le interfacce e la documentazione del codice capisca come funziona il dominio e come si usa (possibilmente senza andare a guardare gli unit tests, a cui comunque anche noi diamo molto peso, cercando di raggiungere almeno il 100% di coverage).
> Come effetto però noi abbiamo una fortissima tipizzazione e gerarchie di oggetti molto basse: all'inizio tutte le entità derivavano da uno storico IBusinessObject, ma per fortuna con sangue sudore e lacrime ce ne siamo ormai liberati per il 95% negli applicativi sviluppati in DDD. Questo ci permette di non violare il Liskow principle (e la definizione di contesti molto ben definiti ci permette di ridurre i rischi di violare l'OCP e il SRP).
> Il riuso del dominio avviene solo quando due clienti ci vedono un aspetto del loro processo/business nello stesso modo (il che succede tanto più di frequente quanto più precisi siamo stati nel definire i contesti di ciascun assembly di dominio).
> Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il business effettivo che le nostre classi modellavano). Agent mi sembra sull'estremo opposto, mi sembra incapsulare il solo comportamento di business, ma senza linea di continuita (ovvero senza identità/entità) e senza stato (non so se mi spiego).
> > > Non conosco GOOS (mai sentito!!! :-O !!!), ma anche noi usiamo molto i mocks sia per testare il dominio che ciò che ne dipende (in particolare i presenter, ma anche gli script di importazione dati per esempio) ed abbiamo adottato da circa un anno una convenzione di naming degli unit test che descrivevo qui <http://www.tesio.it/2010/11/naming-domain-models-unit-tests.html> (in realtà, alcuni miei colleghi già la adottavano da prima... io sono sempre l'ultimo a sapere le cose! :-D).
> > A presto! > > Giacomo > PS: Una considerazione importante: IBusinessObject si rivela distruttivo quando ci SERVE che gli sviluppatori parlino la stessa lingua degli esperti di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core business del cliente (e il cliente, del suo core business, ne sa :-D).
> Al constrario, quando il cliente parla in termini di tabelle e trigger (cosa che ci succede talvolta in industria ed energia) o quando gli applicativi sviluppati si occupano sostanzialmente di analisi dati (molti nostri applicativi sono tool di data mining e business intelligence avanzata, ci chiamiamo Operational Research System non a caso), diventa veramente utile e produttivo.
> E' possibile che voi vi troviate in una situazione simile, sebbene simmetricamente opposta? > > > 2011/8/9 Uberto Barbini <uberto@...> >
> > > > > Ciao Uberto, e benvenuto! > > grazie > > > devo confessare che io invece non sono ancora riuscito a completare il GOOS. L'approccio di Freeman e Pryce mi piace un sacco, e ci sono un sacco di cose che tornano, ...ma non posso ancora dirmi completamente GOOSiano.
> > :) > In goos ci sono moltissime "perle" ma il concetto nuovo di fondo e' fare TDD usando interfacce e mock. > Il risultato e' praticamente BDD, i tuoi test si chiamano shouldBlabla dove blabla e' una "storia" e piu' che testare lo stato con assert vari testi le iterazioni tra l'oggetto "tra i morsetti" e i vari mock.
> Io ne sono entusiasta, soprattutto per come funziona Java. Alcuni colleghi invece si lamentano che (testuali parole) "ma tu dai i dati che vuoi tu al tuo oggetto e testi che esca quello che vuoi tu... in pratica non testi nulla".
> Il punto e' che testi il design e testi ogni singola classe indipendentemente, e' vero che esiste il rischio di misalignment tra test, tipo che testo che la classe A mandi 1 alla classe B ma sui test della classe B testo che A mi mandi 2.
> Pero' proprio stare attenti a questi problemi fa si che il design sia ultra solido IMHO. > > > > Quanto agli aspetti delle side effect free functions e dei Value Object, confermo che ci sono un sacco di punti di contatto: l'effetto che sto sperimentando su di me è che anche i test unitari (l'altra strada che sto battendo al momento è quella di BDD-Cucumber) tendono a migliorare notevolmente la loro leggibilità.
> > si assolutamente. Io ho usato cucumber per test di accettazione, e mi piace molto. I miei test JUnit sono sempre piu' simili a gherkin. > > > L'effetto che mi stai descrivendo mi rammenta qualcosa di cui parlò Matteo Vaccari all'ultima Codemotion, dove in effetti faceva a meno delle entity. Se testi per "fare" qualcosa, la maggior parte dei dati ...non serve. E' solo trasferimento di informazione. Dal punto di vista del comportamento è quasi irrilevante.
> > Con Matteo ci sentiamo spesso e siamo abbastanza allineati. > Qualche volta pero' le Entity servono, per esempio se hai un controller di una UI devi testare che gli stati interni funzionino. > Non ho trovato pero' esempi di oggetti di dominio che avessero bisogno di stati interni.
> Usando oggetti immutabili, funzioni statiche pure per gli algoritmi e agenti per scambiare messaggi sono riuscito finora a rappresentare tutto il dominio. > > > > Io in questo momento sto seguendo un percorso diverso ma probabilmente con qualche analogia di fondo:
> - forte disaccoppiamento degli aggregati > - comunicazione ad eventi tra gli aggregati > La Entity nel mio aggregato, raramente nasce dai dati. A volte li aggiungo alla fine. Per me è sostanzialmente una macchina a stati ed un contenitore di invarianti. Non so se il mio approccio di Entity come macchina a stati (non sempre ...spesso) torna con il tuo, ma ho l'impressione che stiamo vedendo qualcosa di simile.
> > Si anche per me le entity sono macchine a stati e le testo come tali. Ultimamente mi sono anche rispolverato la differenza tra stato inteso come m-configuration e stato inteso come "world". Le entities lavorano solo sul primo, gli agent sul secondo.
> > > >
Non mi è molto chiaro in che modo usiate le entità per mappare stati tecnici.
Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio condiviso fra esperti di dominio e sviluppatori: magari il vostro applicativo gestisce oggetti virtuali, come cache o application pool e tutto tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per stati tecnici.
ok per entity intendevo "oggetto con stato interno modificabile". Lasciando stare il caso di stati tecnici negli adapter che poi non mi interessa, parlando del dominio ho visto che e' molto raro che mi serva una Entity.
Per esempio in GOOS si fa l'esempio di un sistema di aste online, allora e' chiaro li' che mi serve un oggetto con lo stato dell'asta corrente (aperta, chiusa, vincendo, perdendo). Pero' e' un caso raro.
Anche io ho imparato (da Haskell, più che da Evans) il valore dell'immutabilità, però molte entità continuo a vedermele mutabili, anche se solo per un singolo field.
mi fai qualche esempio? come mai ti serve un field mutabile?
Inoltre, quando modello, mi preoccupo che un qualunque collega che non sa niente del contesto in esame e non abbia partecipato alle riunioni con l'esperto del dominio, leggendo le interfacce e la documentazione del codice capisca come funziona il dominio e come si usa (possibilmente senza andare a guardare gli unit tests, a cui comunque anche noi diamo molto peso, cercando di raggiungere almeno il 100% di coverage).
almeno il 100% signica che lo superate spesso? :))) sottoscrivo in pieno, ma preferisco che tutti guardino gli UT prima di lavorare su un oggetto nuovo cosi' se ci sono malintesi (nei test o nell'interfaccia) si possono correggere subito.
Come effetto però noi abbiamo una fortissima tipizzazione e gerarchie di oggetti molto basse: all'inizio tutte le entità derivavano da uno storico IBusinessObject, ma per fortuna con sangue sudore e lacrime ce ne siamo ormai liberati per il 95% negli applicativi sviluppati in DDD. Questo ci permette di non violare il Liskow principle (e la definizione di contesti molto ben definiti ci permette di ridurre i rischi di violare l'OCP e il SRP).
Condivido. Poche classi astratte e gerarchie al massimo a 2 livelli. <rant> Sono anche diventato molto freddo nei confronti del SOLID. Ho visto delle porcate immonde giustificate con SRP (godclass) e OCP (gerarchie infinite). Liskow non lo capisce nessuno, per DI pensano di essere a posto usando Sprint e la IS che forse e' la piu' importante delle 5 non la usa nessuno. E Demeter non e' neppure citato.
</rant>
Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il business effettivo che le nostre classi modellavano). Agent mi sembra sull'estremo opposto, mi sembra incapsulare il solo comportamento di business, ma senza linea di continuita (ovvero senza identità/entità) e senza stato (non so se mi spiego).
Mmmh non ti seguo. Lo stato cerco di toglierlo apposta, lo considero un vantaggio visto che il 90% di bugs derivano da stati mal compresi. L'identita' (che poi deriva dallo stato) era un altra causa di mal di testa felicemente eliminata.
"senza linea di continuita'" --> non sono sicuro di averlo capito. Il risultato come dici tu e' avere "il solo modello di business" senza cercare di modellare oggetti reali con oggetti 1 a 1.
Mi spiego, se faccio un sofware per muovere petroliere non e' che ho bisogno per forza della classe OilTanker come un entity con stato mutevole. Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni volta che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un qualche agent ritornera' una nuova instanza aggiornata, magari con il timestamp della rilevazione.
Questo comunque e' un esempio che ho fatto ora al volo, non dico che sia il sistema migliore, solo che mi sto trovando benissimo.
Non conosco GOOS (mai sentito!!! :-O !!!), ma anche noi usiamo molto i mocks sia per testare il dominio che ciò che ne dipende (in particolare i presenter, ma anche gli script di importazione dati per esempio) ed abbiamo adottato da circa un anno una convenzione di naming degli unit test che descrivevo qui (in realtà, alcuni miei colleghi già la adottavano da prima... io sono sempre l'ultimo a sapere le cose! :-D).
interessante ma preferisco la convenzione bbd/testdox: shouldRaiseExceptionWhenDataIsWrong, shouldReturnCorrectDataAccordingToTimezone ecc.
PS: Una considerazione importante: IBusinessObject si rivela distruttivo quando ci SERVE che gli sviluppatori parlino la stessa lingua degli esperti di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core business del cliente (e il cliente, del suo core business, ne sa :-D).
Al constrario, quando il cliente parla in termini di tabelle e trigger (cosa che ci succede talvolta in industria ed energia) o quando gli applicativi sviluppati si occupano sostanzialmente di analisi dati (molti nostri applicativi sono tool di data mining e business intelligence avanzata, ci chiamiamo Operational Research System non a caso), diventa veramente utile e produttivo.
E' possibile che voi vi troviate in una situazione simile, sebbene simmetricamente opposta?
secondo me quando il cliente parla di tabelle e di trigger siamo fuori dal DDD, e se proprio vuole gli consiglio VB o qualche RAD. :)
Da noi il cliente parla solo per UC utente, piuttosto la seccatura sono gli architetti enterprise... :)
Non mi è molto chiaro in che modo usiate le entità per mappare stati tecnici.
Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio condiviso fra esperti di dominio e sviluppatori: magari il vostro applicativo gestisce oggetti virtuali, come cache o application pool e tutto tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per stati tecnici.
ok per entity intendevo "oggetto con stato interno modificabile". Lasciando stare il caso di stati tecnici negli adapter che poi non mi interessa, parlando del dominio ho visto che e' molto raro che mi serva una Entity.
Per esempio in GOOS si fa l'esempio di un sistema di aste online, allora e' chiaro li' che mi serve un oggetto con lo stato dell'asta corrente (aperta, chiusa, vincendo, perdendo). Pero' e' un caso raro.
Non saprei quanto sia raro.
Certo è che - anche ragionando in termini di Entity, siamo portati a progettare quella classe in termini dei dati che deve contenere. Se invece ragioniamo in termini di test, la classe Customer, a volte non fa niente, e se fa qualcosa dubito che sia un comportamento dipendente dal fatto che il customer si chiami Mario. Al massimo posso avere un comportamento dipendente dall'età (e magari rappresento quella con un VO, con un'implementazione specializzata).
Anche io ho imparato (da Haskell, più che da Evans) il valore dell'immutabilità, però molte entità continuo a vedermele mutabili, anche se solo per un singolo field.
mi fai qualche esempio? come mai ti serve un field mutabile?
Inoltre, quando modello, mi preoccupo che un qualunque collega che non sa niente del contesto in esame e non abbia partecipato alle riunioni con l'esperto del dominio, leggendo le interfacce e la documentazione del codice capisca come funziona il dominio e come si usa (possibilmente senza andare a guardare gli unit tests, a cui comunque anche noi diamo molto peso, cercando di raggiungere almeno il 100% di coverage).
almeno il 100% signica che lo superate spesso? :))) sottoscrivo in pieno, ma preferisco che tutti guardino gli UT prima di lavorare su un oggetto nuovo cosi' se ci sono malintesi (nei test o nell'interfaccia) si possono correggere subito.
Come effetto però noi abbiamo una fortissima tipizzazione e gerarchie di oggetti molto basse: all'inizio tutte le entità derivavano da uno storico IBusinessObject, ma per fortuna con sangue sudore e lacrime ce ne siamo ormai liberati per il 95% negli applicativi sviluppati in DDD. Questo ci permette di non violare il Liskow principle (e la definizione di contesti molto ben definiti ci permette di ridurre i rischi di violare l'OCP e il SRP).
Condivido. Poche classi astratte e gerarchie al massimo a 2 livelli. <rant> Sono anche diventato molto freddo nei confronti del SOLID. Ho visto delle porcate immonde giustificate con SRP (godclass) e OCP (gerarchie infinite). Liskow non lo capisce nessuno, per DI pensano di essere a posto usando Sprint e la IS che forse e' la piu' importante delle 5 non la usa nessuno. E Demeter non e' neppure citato.
</rant>
Senza rantare, SOLID mi torna, ma mi è sempre sembrato molto prescrittivo. Ho sempre preferito i GRASP - che alla fine vanno a toccare gli stessi aspetti.
Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il business effettivo che le nostre classi modellavano). Agent mi sembra sull'estremo opposto, mi sembra incapsulare il solo comportamento di business, ma senza linea di continuita (ovvero senza identità/entità) e senza stato (non so se mi spiego).
Mmmh non ti seguo. Lo stato cerco di toglierlo apposta, lo considero un vantaggio visto che il 90% di bugs derivano da stati mal compresi.
L'identita' (che poi deriva dallo stato) era un altra causa di mal di testa felicemente eliminata.
"senza linea di continuita'" --> non sono sicuro di averlo capito. Il risultato come dici tu e' avere "il solo modello di business" senza cercare di modellare oggetti reali con oggetti 1 a 1.
Mi spiego, se faccio un sofware per muovere petroliere non e' che ho bisogno per forza della classe OilTanker come un entity con stato mutevole. Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni volta che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un qualche agent ritornera' una nuova instanza aggiornata, magari con il timestamp della rilevazione.
In una situazione di questo genere io probabilmente finirei per avere un'aggregate root (Entity) che ha il ruolo di responsabile dell'identità. In caso di variazioni dello stato l'implementazione che di solito mi viene più naturale è lo State Pattern, in cui gli State sarebbero con ogni probabilità dei VO immutabili.
In altri casi, lo stato può essere derivato dall'avere soddisfatto determinate Specification. Ma in questo caso non è detto che la specification si porti dietro il comportamento, è fondamentalmente un modo più elegante di definire dei predicati.
Nell'interpretazione di Niclas Hedman (co-progettista di Qi4J insieme a Rickard Oberg) una Entity può essere ridotta ad un'identità ed una collezione di VO. Non è così lontano da quanto state dicendo voi.
Questo comunque e' un esempio che ho fatto ora al volo, non dico che sia il sistema migliore, solo che mi sto trovando benissimo.
...
PS: Una considerazione importante: IBusinessObject si rivela distruttivo quando ci SERVE che gli sviluppatori parlino la stessa lingua degli esperti di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core business del cliente (e il cliente, del suo core business, ne sa :-D).
Al constrario, quando il cliente parla in termini di tabelle e trigger (cosa che ci succede talvolta in industria ed energia) o quando gli applicativi sviluppati si occupano sostanzialmente di analisi dati (molti nostri applicativi sono tool di data mining e business intelligence avanzata, ci chiamiamo Operational Research System non a caso), diventa veramente utile e produttivo.
E' possibile che voi vi troviate in una situazione simile, sebbene simmetricamente opposta?
secondo me quando il cliente parla di tabelle e di trigger siamo fuori dal DDD, e se proprio vuole gli consiglio VB o qualche RAD. :)
<rant>
Quando il cliente parla di tabelle e trigger, se sono di buon umore cerco di accendere l'iPod. Disegnando quindi nervosamente su un foglio di carta navi che si scontrano con iceberg, esplosioni, corpi dilaniati, avvoltoi che se ne cibano, diavoli con il forcone ed altre amenità del genere. Poi chiedo: "come lo testate?"
</rant>
Da noi il cliente parla solo per UC utente, piuttosto la seccatura sono gli architetti enterprise... :)
Quelli che dicono che "tutto deve essere [stronzata del giorno]" ? ;-)
in realtá c'é qualche altro punto di contatto interessante.
Se ragioni in termini di Eventi, il contenuto informativo, i "dati" per intenderci. Stanno sostanzialmente negli eventi. Gli aggregati gestiscono le transizioni di stato in risposta agli eventi, ma le transizioni di stato dentro in confini dell'aggregato le gestisci come ti pare...salvo buttare fuori un evento al termine della trasformazione.
esatto
C'é un pezzo di ES/CQRS che non ho avuto modo di approfondire, che probabilmente ha punti in comune con quello che stai vedendo te. Penso soprattutto al tuo CustomerRenderer. La trasformazione dai dati in ingresso (comandi o eventi) ai dati in uscita View é gestita in maniera asincrona, spesso prepopolando tabelle o viste che poi vengono sparate "secche" in presentation senza passare dal Domain Model. Ho l'impressione che quello che avviene lí non sia molto diverso da quello che avviene nel tuo renderer. Cambia il momento in cui viene invocato, peró.
non ho mai provato CQRS. Leggendo ora http://martinfowler.com/bliki/CQRS.html mi rendo conto che e' vicino a quello che abbiamo fatto col editorial gwt, ma noi abbiamo usato command patterns anche per le query e questo ci ha comportato una certa complessita' non strettamente necessaria. In effetti CQRS e' un bel passo avanti e mi piacerebbe sicuramente provarlo la prossima volta.
Almeno nel nostro caso pero' c'e' sempre bisogno della business logic, non c'e' mai il caso di crud di dati puri come arrivano dalla persistenza.
Per quanto riguarda i persister, io é da un po' che ho ricominciato a ragionare senza persistenza. Mi faccio i repository, ma in realtá li mocko. Alla fine non c'é molto. E posso decidere abbastanza tardi se andare su SQL o noSQL, etc.
si infatti, per me i persister sono gli adapter (nel senso di architettura esagonale) al "mondo della persistenza", quindi poi posso switcharli facilmente tra db, nosql o file system, senza toccare il domain e l'interfaccia.
L'identita' (che poi deriva dallo stato) era un altra causa di mal di testa felicemente eliminata.
"senza linea di continuita'" --> non sono sicuro di averlo capito. Il risultato come dici tu e' avere "il solo modello di business" senza cercare di modellare oggetti reali con oggetti 1 a 1.
Mi spiego, se faccio un sofware per muovere petroliere non e' che ho bisogno per forza della classe OilTanker come un entity con stato mutevole. Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni volta che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un qualche agent ritornera' una nuova instanza aggiornata, magari con il timestamp della rilevazione.
In una situazione di questo genere io probabilmente finirei per avere un'aggregate root (Entity) che ha il ruolo di responsabile dell'identità. In caso di variazioni dello stato l'implementazione che di solito mi viene più naturale è lo State Pattern, in cui gli State sarebbero con ogni probabilità dei VO immutabili.
Solo una puntualizzazione prima di tornare a lavorare :)
Nel caso dell'asta la mia entity e' veramente l'asta corrente, mentre nel caso della nave la nave vera e' in mezzo al mare e io ho solo delle notificazioni di dove sia e con quale carico. Per quello preferisco avere dei VO con i dati che posseggo piuttosto che simulare la nave, a meno che non stia facendo un sw di simulazione di navi, ovviamente! :)
Lo stesso vale per il customer/supply del solito programma di contabilita', non ho veri clienti, quello che ho e' solo un insieme di informazioni (indirizzo, conto corrente, saldo) da gestire. Nell'esempio dell'asta, o del simulatore di navi da carico, invece ho un vero e proprio "ecosistema vivo" in cui usare entity con stato e' la cosa piu' naturale.
Mi viene in mente ora che forse l'esempio migliore sono invece i videogiochi, dove ho quasi tutte entity che dialogano tra di loro.
In altri casi, lo stato può essere derivato dall'avere soddisfatto determinate Specification. Ma in questo caso non è detto che la specification si porti dietro il comportamento, è fondamentalmente un modo più elegante di definire dei predicati.
il comportamento e' dentro i vari agent, per esempio potrei avere un agent SolvibilityChecker che controlla lo stato dei pagamenti di un cliente e se e' il caso di spedirgli ancora merce a credito.
Nell'interpretazione di Niclas Hedman (co-progettista di Qi4J insieme a Rickard Oberg) una Entity può essere ridotta ad un'identità ed una collezione di VO. Non è così lontano da quanto state dicendo voi.
Ottimo! Me lo vado a cercare (come pure GRASP che non conoscevo).
<rant>
Quando il cliente parla di tabelle e trigger, se sono di buon umore cerco di accendere l'iPod. Disegnando quindi nervosamente su un foglio di carta navi che si scontrano con iceberg, esplosioni, corpi dilaniati, avvoltoi che se ne cibano, diavoli con il forcone ed altre amenità del genere. Poi chiedo: "come lo testate?"
</rant>
lol
Da noi il cliente parla solo per UC utente, piuttosto la seccatura sono gli architetti enterprise... :)
Quelli che dicono che "tutto deve essere [stronzata del giorno]" ? ;-)
...li adoro.
si esatto! credo dipenda da cosa hanno letto nella loro rivista durante il weekend :)
Il giorno 10 agosto 2011 14:35, Uberto Barbini <uberto@...> ha scritto:
L'identita' (che poi deriva dallo stato) era un altra causa di mal di testa felicemente eliminata.
"senza linea di continuita'" --> non sono sicuro di averlo capito. Il risultato come dici tu e' avere "il solo modello di business" senza cercare di modellare oggetti reali con oggetti 1 a 1.
Mi spiego, se faccio un sofware per muovere petroliere non e' che ho bisogno per forza della classe OilTanker come un entity con stato mutevole. Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni volta che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un qualche agent ritornera' una nuova instanza aggiornata, magari con il timestamp della rilevazione.
In una situazione di questo genere io probabilmente finirei per avere un'aggregate root (Entity) che ha il ruolo di responsabile dell'identità. In caso di variazioni dello stato l'implementazione che di solito mi viene più naturale è lo State Pattern, in cui gli State sarebbero con ogni probabilità dei VO immutabili.
Solo una puntualizzazione prima di tornare a lavorare :)
Nel caso dell'asta la mia entity e' veramente l'asta corrente, mentre nel caso della nave la nave vera e' in mezzo al mare e io ho solo delle notificazioni di dove sia e con quale carico. Per quello preferisco avere dei VO con i dati che posseggo piuttosto che simulare la nave, a meno che non stia facendo un sw di simulazione di navi, ovviamente! :)
Distinzione interessante.
Ora dovrò fare un po' di mumble mumble per capire se ci sono conseguenze. A naso mi verrebbe da dire che "sì, rappresento una cosa invece che una proiezione della cosa" però sostanzialmente sono comunque aggregati che ricevono comandi o notifiche. Che questi siano lo spostamento di un rilevamento satellitare una volta ogni 3 ore o un comando dal client del partecipante all'asta ...dovrebbe essere la stessa cosa. Però il mumble mumble sta girando ancora...
Lo stesso vale per il customer/supply del solito programma di contabilita', non ho veri clienti, quello che ho e' solo un insieme di informazioni (indirizzo, conto corrente, saldo) da gestire. Nell'esempio dell'asta, o del simulatore di navi da carico, invece ho un vero e proprio "ecosistema vivo" in cui usare entity con stato e' la cosa piu' naturale.
Mi viene in mente ora che forse l'esempio migliore sono invece i videogiochi, dove ho quasi tutte entity che dialogano tra di loro.
bell'esempio. ma anche con la contabilità posso mandarti eventi (i movimenti) in maniera sincrona e/o differita. Dovrebbe stare su.
P.S. sono reduce da una maratona di birra & rivelazioni con Greg Young, che ha messo sul piatto il fatto che Alan Kay avesse già capito tutto e che i sistemi ad oggetti - nella sua concezione Smalltalkiana - non fossero diversi da quello che è diventata la rete (Kay oltre ad essere uno dei padri di Smalltalk era stato anche al DARPA): componenti che parlano tramite messaggi. Il fatto che siano remoti o locali
In altri casi, lo stato può essere derivato dall'avere soddisfatto determinate Specification. Ma in questo caso non è detto che la specification si porti dietro il comportamento, è fondamentalmente un modo più elegante di definire dei predicati.
il comportamento e' dentro i vari agent, per esempio potrei avere un agent SolvibilityChecker che controlla lo stato dei pagamenti di un cliente e se e' il caso di spedirgli ancora merce a credito.
Quello per me è una Specification. Qualcosa come
IsEligibleForLatePaymentDeliverySpecification
che implementa isSatisfied()
Nell'interpretazione di Niclas Hedman (co-progettista di Qi4J insieme a Rickard Oberg) una Entity può essere ridotta ad un'identità ed una collezione di VO. Non è così lontano da quanto state dicendo voi.
Ottimo! Me lo vado a cercare (come pure GRASP che non conoscevo).
GRASP è di scuola Craig Larman. "Applying UML and Patterns". Gran libro con titolo riduttivo: non è solo UML, anzi. E' una scusa per parlare di OOP e processo di sviluppo.
Non mi è molto chiaro in che modo usiate le entità per mappare stati tecnici.
Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio condiviso fra esperti di dominio e sviluppatori: magari il vostro applicativo gestisce oggetti virtuali, come cache o application pool e tutto tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per stati tecnici.
ok per entity intendevo "oggetto con stato interno modificabile".
Capito. Noi invece per entità intendiamo quei modelli che hanno un identità condivisa fra tutti gli attori legati al software (gli utenti, ma anche i dba e gli sviluppatori che devono fixare bug).
Nulla a che fare con lo stato e la sua mutabilità.
Per esempio in un contesto abbiamo modellato gli strumenti finanziari come entità immutabili (il prezzo viene determinato dal mercato, che invece è un entità mutabile e di conseguenza osservabile); in un altro contesto gli strumenti finanziari sono entità mutabili ed osservabili (ma in questo contesto parla di invio ordini etc...)
Altre entità tipicamente mutabili sono i Customer: oltre al nome e cognome (che comunque non è così inutile in termini di business) abbiamo il profilo MIFID (che sostanzialmente è una specification utilizzata per selezionare gli strumenti finanziari proponibili, ma è costruita in termini di risultati di una intervista).
Anche io ho imparato (da Haskell, più che da Evans) il valore dell'immutabilità, però molte entità continuo a vedermele mutabili, anche se solo per un singolo field.
mi fai qualche esempio? come mai ti serve un field mutabile?
Per esempio i clienti dei private banker possono cambiare profilo mifid nel tempo.
In realtà all'inizio non avevamo un solo field mutabile ne avevamo molti di più.. è stato un punto di arrivo di un anno e mezzo fa circa, che ha nettamente semplificato gli unit test e permesso figate assurde in altri ambiti (anche se ha reso molto maggiore il numero di classi scritte, una per stato)
Inoltre, quando modello, mi preoccupo che un qualunque collega che non sa niente del contesto in esame e non abbia partecipato alle riunioni con l'esperto del dominio, leggendo le interfacce e la documentazione del codice capisca come funziona il dominio e come si usa (possibilmente senza andare a guardare gli unit tests, a cui comunque anche noi diamo molto peso, cercando di raggiungere almeno il 100% di coverage).
almeno il 100% signica che lo superate spesso? :)))
Sì. Sul domain model abbastanza...
Nel senso che cerchiamo di testare ogni singolo metodo in modo da coprire tutti i possibili casi fra precondizioni e post condizioni (anche quando alcune linee sono già attraversate da altri test)
Comunque, ovviamente siamo tanto più metodici quanto più è strategico il contesto in questione.
Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il business effettivo che le nostre classi modellavano). Agent mi sembra sull'estremo opposto, mi sembra incapsulare il solo comportamento di business, ma senza linea di continuita (ovvero senza identità/entità) e senza stato (non so se mi spiego).
Mmmh non ti seguo. Lo stato cerco di toglierlo apposta, lo considero un vantaggio visto che il 90% di bugs derivano da stati mal compresi. L'identita' (che poi deriva dallo stato) era un altra causa di mal di testa felicemente eliminata.
Mah il problema sostanziale è che il prezzo delle azioni IT0001976403 (ovvero FIAT) non è solo un valore... quel ISIN identifica un'entità di cui gli operatori finanziari sono ben conscienti.
Noi cerchiamo di evitare nel dominio qualsiasi astrazione che non sia nota agli esperti di dominio, in modo che l'applicativo rispecchi fedelmente il loro modo di pensare.
Ho paura di non riuscire ad esprimere il concetto...
"senza linea di continuita'" --> non sono sicuro di averlo capito.
Intendo che se non identifichi chiaramente il titolo azionario di FIAT, come fai a sapere quando e come è variato il suo prezzo? e come fai a venderne le azioni (o ad acquistarle, ma di questi tempi... :-D)?
Il risultato come dici tu e' avere "il solo modello di business" senza cercare di modellare oggetti reali con oggetti 1 a 1.
Questo non cerchiamo di farlo neanche noi.
Noi cerchiamo di modellare la visione degli esperti di dominio sul contesto del problema.
Forse è proprio l'interazione con gli esperti di dominio che definisce il DDD.
Mi spiego, se faccio un sofware per muovere petroliere non e' che ho bisogno per forza della classe OilTanker come un entity con stato mutevole. Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni volta che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un qualche agent ritornera' una nuova instanza aggiornata, magari con il timestamp della rilevazione.
Se gli utenti, quando parlano fra loro, utilizzano il termine OilTanker's Situation le nostre visioni convergono.
PS: Una considerazione importante: IBusinessObject si rivela distruttivo quando ci SERVE che gli sviluppatori parlino la stessa lingua degli esperti di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core business del cliente (e il cliente, del suo core business, ne sa :-D).
Al constrario, quando il cliente parla in termini di tabelle e trigger (cosa che ci succede talvolta in industria ed energia) o quando gli applicativi sviluppati si occupano sostanzialmente di analisi dati (molti nostri applicativi sono tool di data mining e business intelligence avanzata, ci chiamiamo Operational Research System non a caso), diventa veramente utile e produttivo.
E' possibile che voi vi troviate in una situazione simile, sebbene simmetricamente opposta?
secondo me quando il cliente parla di tabelle e di trigger siamo fuori dal DDD, e se proprio vuole gli consiglio VB o qualche RAD. :)
Mmm... non so... la mia personale opinione è che un cliente che ti parla di tabelle e trigger ha bisogno di elaborazioni dati che hanno tutta la dignità del fatto che è disposto a pagarle per utilizzarle.
Solo una puntualizzazione prima di tornare a lavorare :)
hi hi... io vi scrivo dalle ferie... :-P
Nel caso dell'asta la mia entity e' veramente l'asta corrente, mentre nel caso della nave la nave vera e' in mezzo al mare e io ho solo delle notificazioni di dove sia e con quale carico. Per quello preferisco avere dei VO con i dati che posseggo piuttosto che simulare la nave, a meno che non stia facendo un sw di simulazione di navi, ovviamente! :)
Ecco su questo forse non siamo d'accordo.
Nel contesto che stai descrivendo una nave E' un carico, con una collocazione (e probabilmente un tragitto ed una meta).
Non ha lo scafo, la poppa e la prua, perché nel contesto in esame sono irrilevanti, ma è una nave (o un viaggio, o qualunque altro termine che l'esperto di dominio trovi corretto).
P.S. sono reduce da una maratona di birra & rivelazioni con Greg Young, che ha messo sul piatto il fatto che Alan Kay avesse già capito tutto e che i sistemi ad oggetti - nella sua concezione Smalltalkiana - non fossero diversi da quello che è diventata la rete (Kay oltre ad essere uno dei padri di Smalltalk era stato anche al DARPA): componenti che parlano tramite messaggi. Il fatto che siano remoti o locali
si assolutamente! E' anche il tema fondamentale dell'intervento che ho proposto all'AgileDay: Alan Kay aveva capito tutto ma la OOP che si insegna oggi per la maggiore e' pseudo-procedurale.
Non mi è molto chiaro in che modo usiate le entità per mappare stati tecnici.
Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio condiviso fra esperti di dominio e sviluppatori: magari il vostro applicativo gestisce oggetti virtuali, come cache o application pool e tutto tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per stati tecnici.
ok per entity intendevo "oggetto con stato interno modificabile".
Capito. Noi invece per entità intendiamo quei modelli che hanno un identità condivisa fra tutti gli attori legati al software (gli utenti, ma anche i dba e gli sviluppatori che devono fixare bug).
Nulla a che fare con lo stato e la sua mutabilità.
Per esempio in un contesto abbiamo modellato gli strumenti finanziari come entità immutabili (il prezzo viene determinato dal mercato, che invece è un entità mutabile e di conseguenza osservabile); in un altro contesto gli strumenti finanziari sono entità mutabili ed osservabili (ma in questo contesto parla di invio ordini etc...)
Altre entità tipicamente mutabili sono i Customer: oltre al nome e cognome (che comunque non è così inutile in termini di business) abbiamo il profilo MIFID (che sostanzialmente è una specification utilizzata per selezionare gli strumenti finanziari proponibili, ma è costruita in termini di risultati di una intervista).
... in termine di business, no. In termini di comportamento, meno.
Mi aspetto che si possa/debba utilizzare il dato anagrafico per fare ricerche, verifiche su solvibilità etc.
Anche io ho imparato (da Haskell, più che da Evans) il valore dell'immutabilità, però molte entità continuo a vedermele mutabili, anche se solo per un singolo field.
mi fai qualche esempio? come mai ti serve un field mutabile?
Per esempio i clienti dei private banker possono cambiare profilo mifid nel tempo.
In realtà all'inizio non avevamo un solo field mutabile ne avevamo molti di più.. è stato un punto di arrivo di un anno e mezzo fa circa, che ha nettamente semplificato gli unit test e permesso figate assurde in altri ambiti (anche se ha reso molto maggiore il numero di classi scritte, una per stato)
in DDD-by-the-book il ProfiloMIFID sarebbe un VO.
in Event Sourcing riceverei l'evento ProfiloMIFIDAggiornato (con tanto di info all'interno) e la mia getProfiloMIFID mi restituirebbe l'ultimo.
almeno il 100% signica che lo superate spesso? :)))
Sì. Sul domain model abbastanza...
Nel senso che cerchiamo di testare ogni singolo metodo in modo da coprire tutti i possibili casi fra precondizioni e post condizioni (anche quando alcune linee sono già attraversate da altri test)
Comunque, ovviamente siamo tanto più metodici quanto più è strategico il contesto in questione.
Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il business effettivo che le nostre classi modellavano). Agent mi sembra sull'estremo opposto, mi sembra incapsulare il solo comportamento di business, ma senza linea di continuita (ovvero senza identità/entità) e senza stato (non so se mi spiego).
Mmmh non ti seguo. Lo stato cerco di toglierlo apposta, lo considero un vantaggio visto che il 90% di bugs derivano da stati mal compresi. L'identita' (che poi deriva dallo stato) era un altra causa di mal di testa felicemente eliminata.
Mah il problema sostanziale è che il prezzo delle azioni IT0001976403 (ovvero FIAT) non è solo un valore... quel ISIN identifica un'entità di cui gli operatori finanziari sono ben conscienti.
Anche in questo caso avresti una identità e quindi un'entity che serve per gestire una catena di eventi price update. Il current price (invento termini a caso) sarebbe derivato dagli ultimi eventi ricevuti.
Noi cerchiamo di evitare nel dominio qualsiasi astrazione che non sia nota agli esperti di dominio, in modo che l'applicativo rispecchi fedelmente il loro modo di pensare.
Ho paura di non riuscire ad esprimere il concetto...
"senza linea di continuita'" --> non sono sicuro di averlo capito.
Intendo che se non identifichi chiaramente il titolo azionario di FIAT, come fai a sapere quando e come è variato il suo prezzo? e come fai a venderne le azioni (o ad acquistarle, ma di questi tempi... :-D)?
Il risultato come dici tu e' avere "il solo modello di business" senza cercare di modellare oggetti reali con oggetti 1 a 1.
Questo non cerchiamo di farlo neanche noi.
Noi cerchiamo di modellare la visione degli esperti di dominio sul contesto del problema.
Forse è proprio l'interazione con gli esperti di dominio che definisce il DDD.
Ne è un bel pezzo. ;-)
Mi spiego, se faccio un sofware per muovere petroliere non e' che ho bisogno per forza della classe OilTanker come un entity con stato mutevole. Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni volta che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un qualche agent ritornera' una nuova instanza aggiornata, magari con il timestamp della rilevazione.
Se gli utenti, quando parlano fra loro, utilizzano il termine OilTanker's Situation le nostre visioni convergono.
PS: Una considerazione importante: IBusinessObject si rivela distruttivo quando ci SERVE che gli sviluppatori parlino la stessa lingua degli esperti di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core business del cliente (e il cliente, del suo core business, ne sa :-D).
Al constrario, quando il cliente parla in termini di tabelle e trigger (cosa che ci succede talvolta in industria ed energia) o quando gli applicativi sviluppati si occupano sostanzialmente di analisi dati (molti nostri applicativi sono tool di data mining e business intelligence avanzata, ci chiamiamo Operational Research System non a caso), diventa veramente utile e produttivo.
E' possibile che voi vi troviate in una situazione simile, sebbene simmetricamente opposta?
secondo me quando il cliente parla di tabelle e di trigger siamo fuori dal DDD, e se proprio vuole gli consiglio VB o qualche RAD. :)
Mmm... non so... la mia personale opinione è che un cliente che ti parla di tabelle e trigger ha bisogno di elaborazioni dati che hanno tutta la dignità del fatto che è disposto a pagarle per utilizzarle.
Infatti. Io ho fatto il patacca.
Ma io parto dall'ipotesi di essere chiamato anche per fare DDD. Trigger e DDD vanno poco d'accordo.
Ma allora la lista è viva! ogni tanto ci sono dei barlumi di esistenza e
saggezza distillata :-)
Ragazzi rileggendo tutti i vostri messaggi sono colto da una sensazione a metà
tra l'invidia per la vostra competenza e la tristezza per non riuscire ad
arrivare a quei livelli... ma se penso che ora me ne devo tornare fuori sotto il
sole cocente a piastrellare la discesa del box penso che alla fine c'è di peggio
che scrivere codice non ottimale :-)
--- In DDD-IT@yahoogroups.com, Alberto Brandolini <alberto.brandolini@...> ha
scritto:
>
> >
> > Non mi è molto chiaro in che modo usiate le entità per mappare stati
> >>> tecnici.
> >>>
> >>> Un'entità è un oggetto identificabile nel tempo e presente nel linguaggio
> >>> condiviso fra esperti di dominio e sviluppatori: magari il vostro
> >>> applicativo gestisce oggetti virtuali, come cache o application pool e
tutto
> >>> tornerebbe perfettamente, ma non mi è chiaro cosa intendessi allora per
> >>> stati tecnici.
> >>>
> >>
> >> ok per entity intendevo "oggetto con stato interno modificabile".
> >>
> >
> > Capito. Noi invece per entità intendiamo quei modelli che hanno un identità
> > condivisa fra tutti gli attori legati al software (gli utenti, ma anche i
> > dba e gli sviluppatori che devono fixare bug).
> >
> > Nulla a che fare con lo stato e la sua mutabilità.
> > Per esempio in un contesto abbiamo modellato gli strumenti finanziari come
> > entità immutabili (il prezzo viene determinato dal mercato, che invece è un
> > entità mutabile e di conseguenza osservabile); in un altro contesto gli
> > strumenti finanziari sono entità mutabili ed osservabili (ma in questo
> > contesto parla di invio ordini etc...)
> >
> > Altre entità tipicamente mutabili sono i Customer: oltre al nome e cognome
> > (che comunque non è così inutile in termini di business) abbiamo il profilo
> > MIFID (che sostanzialmente è una specification utilizzata per selezionare
> > gli strumenti finanziari proponibili, ma è costruita in termini di risultati
> > di una intervista).
> >
>
> ... in termine di business, no. In termini di comportamento, meno.
> Mi aspetto che si possa/debba utilizzare il dato anagrafico per fare
> ricerche, verifiche su solvibilità etc.
>
>
> >
> >
> >> Anche io ho imparato (da Haskell, più che da Evans) il valore
> >>> dell'immutabilità, però molte entità continuo a vedermele mutabili, anche
se
> >>> solo per un singolo
field<http://epic.tesio.it/doc/single_mutable_state.html>
> >>> .
> >>>
> >>
> >> mi fai qualche esempio? come mai ti serve un field mutabile?
> >>
> >
> > Per esempio i clienti dei private banker possono cambiare profilo mifid nel
> > tempo.
> > In realtà all'inizio non avevamo un solo field mutabile ne avevamo molti di
> > più.. è stato un punto di arrivo di un anno e mezzo fa circa, che ha
> > nettamente semplificato gli unit test e permesso figate assurde in altri
> > ambiti (anche se ha reso molto maggiore il numero di classi scritte, una per
> > stato)
> >
>
> in DDD-by-the-book il ProfiloMIFID sarebbe un VO.
> in Event Sourcing riceverei l'evento ProfiloMIFIDAggiornato (con tanto di
> info all'interno) e la mia getProfiloMIFID mi restituirebbe l'ultimo.
>
>
> >
> >
> >> almeno il 100% signica che lo superate spesso? :)))
> >>
> >
> > Sì. Sul domain model abbastanza...
> >
> > Nel senso che cerchiamo di testare ogni singolo metodo in modo da coprire
> > tutti i possibili casi fra precondizioni e post condizioni (anche quando
> > alcune linee sono già attraversate da altri test)
> >
> > Comunque, ovviamente siamo tanto più metodici quanto più è strategico il
> > contesto in questione.
> >
> >
> >> Il sistema di agenti che descrivi mi sembra pericoloso quanto il nostro
> >>> vecchio IBusinessObject, che permetteva di vedere tutto nello stesso modo
> >>> (molto CRUD) ma ti faceva completamente perdere il dettaglio (ovvero il
> >>> business effettivo che le nostre classi modellavano). Agent mi sembra
> >>> sull'estremo opposto, mi sembra incapsulare il solo comportamento di
> >>> business, ma senza linea di continuita (ovvero senza identità/entità) e
> >>> senza stato (non so se mi spiego).
> >>>
> >>>
> >> Mmmh non ti seguo. Lo stato cerco di toglierlo apposta, lo considero un
> >> vantaggio visto che il 90% di bugs derivano da stati mal compresi.
> >> L'identita' (che poi deriva dallo stato) era un altra causa di mal di
> >> testa felicemente eliminata.
> >>
> >
> > Mah il problema sostanziale è che il prezzo delle azioni IT0001976403
> > (ovvero FIAT) non è solo un valore... quel ISIN identifica un'entità di cui
> > gli operatori finanziari sono ben conscienti.
> >
> > Anche in questo caso avresti una identità e quindi un'entity che serve per
> gestire una catena di eventi price update. Il current price (invento termini
> a caso) sarebbe derivato dagli ultimi eventi ricevuti.
>
>
> > Noi cerchiamo di evitare nel dominio qualsiasi astrazione che non sia nota
> > agli esperti di dominio, in modo che l'applicativo rispecchi fedelmente il
> > loro modo di pensare.
> >
> > Ho paura di non riuscire ad esprimere il concetto...
> >
> >
> >> "senza linea di continuita'" --> non sono sicuro di averlo capito.
> >>
> >
> > Intendo che se non identifichi chiaramente il titolo azionario di FIAT,
> > come fai a sapere quando e come è variato il suo prezzo? e come fai a
> > venderne le azioni (o ad acquistarle, ma di questi tempi... :-D)?
> >
> >
> >> Il risultato come dici tu e' avere "il solo modello di business" senza
> >> cercare di modellare oggetti reali con oggetti 1 a 1.
> >>
> >
> > Questo non cerchiamo di farlo neanche noi.
> >
> > Noi cerchiamo di modellare la visione degli esperti di dominio sul contesto
> > del problema.
> > Forse è proprio l'interazione con gli esperti di dominio che definisce il
> > DDD.
> >
>
> Ne è un bel pezzo. ;-)
>
> >
> >
> >> Mi spiego, se faccio un sofware per muovere petroliere non e' che ho
> >> bisogno per forza della classe OilTanker come un entity con stato mutevole.
> >> Preferisco avere oggetti immutabili di tipo OilTankerSituation ed ogni
volta
> >> che ho nuove informazioni sulla posizione o sul carico del mio oilTanker un
> >> qualche agent ritornera' una nuova instanza aggiornata, magari con il
> >> timestamp della rilevazione.
> >>
> >
> > Se gli utenti, quando parlano fra loro, utilizzano il termine OilTanker's
> > Situation le nostre visioni convergono.
> >
> >
> >>
> >>> PS: Una considerazione importante: IBusinessObject si rivela distruttivo
> >>> quando ci SERVE che gli sviluppatori parlino la stessa lingua degli
esperti
> >>> di dominio (e degli utenti), ovvero tipicamente quando lavoriamo sul core
> >>> business del cliente (e il cliente, del suo core business, ne sa :-D).
> >>> Al constrario, quando il cliente parla in termini di tabelle e trigger
> >>> (cosa che ci succede talvolta in industria ed energia) o quando gli
> >>> applicativi sviluppati si occupano sostanzialmente di analisi dati (molti
> >>> nostri applicativi sono tool di data mining e business intelligence
> >>> avanzata, ci chiamiamo Operational Research System non a caso), diventa
> >>> veramente utile e produttivo.
> >>> E' possibile che voi vi troviate in una situazione simile, sebbene
> >>> simmetricamente opposta?
> >>>
> >>
> >> secondo me quando il cliente parla di tabelle e di trigger siamo fuori dal
> >> DDD, e se proprio vuole gli consiglio VB o qualche RAD. :)
> >>
> >
> > Mmm... non so... la mia personale opinione è che un cliente che ti parla di
> > tabelle e trigger ha bisogno di elaborazioni dati che hanno tutta la dignità
> > del fatto che è disposto a pagarle per utilizzarle.
> >
>
> Infatti. Io ho fatto il patacca.
> Ma io parto dall'ipotesi di essere chiamato anche per fare DDD. Trigger e
> DDD vanno poco d'accordo.
>
> Brando
> --
> Alberto Brandolini
> Phone: +39-347-6005027
>
> E-mail: alberto.brandolini@...
> Twitter: @ziobrando
>
> Company: http://www.avanscoperta.it
> Blog: http://ziobrando.blogspot.com
> Linkedin page: http://www.linkedin.com/in/brando
>
Qua è pieno di gente che fa le cose per bene e poi non lo dice in giro. :-D
ogni tanto ci sono dei barlumi di esistenza e saggezza distillata :-)
Ragazzi rileggendo tutti i vostri messaggi sono colto da una sensazione a metà tra l'invidia per la vostra competenza e la tristezza per non riuscire ad arrivare a quei livelli... ma se penso che ora me ne devo tornare fuori sotto il sole cocente a piastrellare la discesa del box penso che alla fine c'è di peggio che scrivere codice non ottimale :-)
Puoi sempre fare exploratory tiling ;-)
a parte questo, rileggendo il tono dei miei interventi ...è un po' troppo didattico. :-P spesso mi calo nel ruolo del docente DDD anche fuori contesto. Però la discussione era decisamente stimolante :-)