In questo periodo mi sto occupando dello sviluppo di un interessante applicazione distribuita, l'applicazione alla fine è il "solito" gestionale quello che lo rende interessante per lo sviluppatore, almeno per lo sviluppatore che c'è in me ;-), sono caratteristiche come:

  • è distribuita, il cliente ha più di una sede;
  • il collegamento tra le sedi non è "garantito", quindi le sedi devono poter lavorare in off-line tra loro e sincronizzarsi;
  • i client devono poter lavorare, in maniera trasparente (sul modello di Outlook 2003 con Cached Exchange Mode), disconnessi e anch'essi sincronizzare le modifiche all'uopo.
  • l'applicazione dovrà integrarsi con un software di contabilità esistente che non offre nessuna soluzione facile all'integrazione.. l'idea è quella di inventarsi una sorta di front-end basato o su Remoting o su Web Services ( e perchè non WCF ) per poter poi dialogare in maniera agevole.

Uno degli obiettivi principi è la "modularità", in questo senso uno dei primi ostacoli che abbiamo trovato è stata nella gestione dei "listini" (intesi come listini di vendita), il cliente ha una serie di prodotti commercializzati e una produzione propria, nonostante i prodotti siano fondamentalmente della stessa categoria sono però radicalmente diversi dal punto di vista della gestione.

La prima proposta è stata naturalmente:

"Be' dove sta il problema verticalizziamo, spieghiamo al ns sistema come funziona ogni singolo prodotto e andiamo avanti..."

Sarà..., ma a me il termine verticalizzazione già da solo mi fa venire l'orticaria, se poi lo associo al fatto che la conseguenza sono le mani legate di fronte a futuri sviluppi l'orticaria si trasforma in orch*te :-D

Quindi mi sono armato di santa pazienza e mi sono impuntato, dicendo no.
Ho passato qualche giorno con il naso all'insù a ragionare su una architettura che risolvesse elegantemente il problema senza rendermi conto che ce l'ho sotto il naso ormai da qualche anno...

Ebbens si "Visual Studio" e la gestione dei Component(s)/Control(s), Visual Studio è in grado di gestire un Control non tanto perchè conosce nello specifico quel particolare control ma bensì perchè conosce la sua firma di base (quella di System.Windows.Forms.Control) e sa che quel determinato controllo potrebbe implementare delle interfaccie o essere marcato con attributi che ad esempio spiegano come invocare partiolari Designer o particolari TypeConverter, e chi più ne ha più ne metta.
Questo sofisticato meccanismo è quello che ci permette di sviluppare i ns controlli custom, aggiungerli alla Tool Bar di Visual Studio e vedere che miracolosamente questi vengono gestiti come i controlli builtin del framework, con la possibilità di essere draggati, configurati e manipolati sul designer...

Mi sono "armato" di carta e penna e ho disegnato il mio bel modello mettendo da una parte del muro il ns gestionale e dall'altra i "prodotti", alla fine ho realizzato un prototipo del sistema che funziona egregiamente (già adesso sia in ambiente Web che Windows Forms).

E' quindi possibile comportarsi esattamente come ci si comporta con Visual Studio, è possibile scegliere un Assembly, visualizzare tutti i Prodotti definiti nell'assembly caricato e aggiungere una reference al prodotto scelto, da quel momento in poi l'applicazione è in grado di dialogare alla perfezione con il nuovo prodotto grazie ad una serie di "designer" e "configurator", proprio come farebbe Visual Studio attraverso la property grid e le sue estensioni.

Il modello è decisamente "semplice", cuore del sistema sono le classi:

  • "Product" (abstract) la classe base per ogni prodotto;
  • "Settings" la classe base per gestire (e in particolare persistere) i settaggi di ogni singolo prodotto;
  • "Settings.ExtendedData" (abstract) da cui i prodotti specializzati possono derivare per aggiungere propri settings specifici, l'unico requisito è la serializzabilità del dato;
  • "ProductDesignerProvider" la classe con cui l'applicazione è in grado di interagire per invocare i designer per i prodotti specializzati;
  • "ProductDesigner" il designer vero e proprio, nel caso di un'applicazione Windows Forms ad esempio uno UserControl, che verrà invocato dal suo "ProductDesignerProvider";

L'applicazione è in grado di capire quali "designer" e quali "designer provider" utilizare grazie ad una serie di attributi con cui sono marcate le classi specializzate dei prodotti.

Il lavoro da fare è ancora molto, ma quello realizzato sino ad ora è decisamente soddisfacente. Ho appena cominciato ad abbozzare i "ProductConfigurator" che sul modello dei ProductDesigner permetteranno all'utente di selezionare un prodotto configurarlo per le sue necessità e inserirlo in un'offerta, o in un ordine o in una commessa pronta per la produzione

Il passaggio successivo sarà quello di realizzare dei "renderer" finalizzati a renderizzare il "listino" e quindi i singoli prodotti su una superficie, sia essa il video o la carta di una stampante... in questa direzione mi alletta molto WPF ma sia i tempi stretti che la curva di apprendimento di WPF mi fanno propendere per una soluzione "tradizionale".

Il vero pregio di questo modello? Semplicemente che consente di aggiungere a "caldo" nuovi prodotti senza preoccuparsi di dover redistribuire l'applicazione, ma non solo permette a chiunque, con la dovuta documentazione alla mano, di sviluppare un nuovo prodotto, proprio come si farebbe con un controllo per Visual Studio.

Stay tuned ;-)

.m