Programming

Layer, il mio personale approccio al problema (Parte II)

In questa seconda parte (qui la prima) completerò la parte applicativa introducendo lo strato di factory e cercherò di fare un'analisi, spero oggettiva, del laro svolto dei sui limiti e presenterò alcune soluzioni a questi limiti. Factory LayerNella mia ottica il factory si occupa solo ed esclusivamente della generazione delle istanze delle classi di business, il factory conosce molto bene lo strato di business. Partiamo, come sempre, dal codice che non differisce molto da quello presentato nel precedente articolo riguardo allo strato di persistenza: //// ASSEMBLY// Topics.Common.Factory.dll//public sealed class FactoryEngine{    private FactoryEngine()    {        }    private static FactoryEngine _engine;        /*        Singleton    */    public static FactoryEngine Engine    {        get        {            if( _engine == null )            {                _engine = new FactoryEngine();            }                        return _engine;        }    }        private MyCustomerFactory _myCustomers    public MyCustomerFactory MyCustomers    {        get        {            if( this._myCustomers == null )            {                this._myCustomers = MyCustomerFactory.CreateInstance();            }                        return this._myCustomers;        }    }}public abstract class MyCustomerFactory{    public static MyCustomerFactory CreateInstance()    {        /*            OMISSIS            Legge da file .config quale tipo di            Factory debba istanziare e da quale            assembly, tramite Activator.CreateInstance( ... )            inizializza la classe "reale" corretta        */    }        /*        MyCustomerCollection (omissis) è una semplice         collection fortemente tipizzata di MyCustomers    */    public abstract MyCustomerCollection FindCustomersByCompanyName( string companyName );    public abstract MyCustomer FindByGuid( Guid pk );}//// ASSEMBLY// Topics.MyApplication.SqlFactory.dll//public class MyCustomerSqlFactory : MyCustomerFactory{    public override MyCustomerCollection FindCustomersByCompanyName( string companyName )    {        //Si connette a SQL                //Invoca la SP del caso                //Ottiene un SqlDataReader (IDataReader)                //Crea la collection passando al costruttore il DataReader    }        public override MyCustomer FindByGuid( Guid pk )    {        //Si connette a SQL                //Invoca la SP del caso                //Ottiene un SqlDataReader (IDataReader)                //Crea l'istanza della classe passando al costruttore il DataReader    }} Anche qui vale la stessa regola esposta per lo strato di persistenza, possiamo sostituire il tipo factory a caldo...

posted @ martedì 23 agosto 2005 23.40 | Feedback (0)

Layer, il mio personale approccio al problema (Parte I)

Approfitto di questi schermi per... Ogni tanto (IMHO non abbastanza) sui NewsGroup si parla di design e l'argomento principe per chi si sta approcciando al problema è quasi sempre la stratificazione (suddivisione in Layer) delle applicazioni.Naturalmente il "problema" l'ho dovuto sviscerare anche io e dopo varie reimplementazioni l'ho "rilsolto" (almeno per ora). Quando sono di fronte ad applicazioni di un certo "spessore" la struttura è sintetizzabile così: Domain LayerRappresenta lo strato di business e contiene tutte le classi/entities necessarie.Una esempio tipo di business entity(s) potrebbe essere: //// ASSEMBLY// Topics.Common.dll///*    MyObject è la classe di base da cui tutte le     entity del mio framework erditano*/public abstract class MyObject{    protected virtual void Initialize( System.Data.IDataReader reader )    {        if( reader == null )        {            /*            L'istanza rappresenta un nuovo oggetto            quindi inizializziamo i field con i            valori di default            */            this._uid = Guid.NewGuid();            this._description = String.Empty;                        this._isNew = true;        }        else        {            this._uid = reader.GetGuid( reader.GetOrdinal( "UID" ) );            this._description = reader.GetString( reader.GetOrdinal( "Description" ) );                        this._isNew = false;        }    }        protected MyObject( System.Data.IDataReader reader )    {        if( reader == null )        {            throw new ArgumentException( "Invalid Source" );        }                this.Initialize( reader );    }        protected MyObject()    {        this.Initialize( null );    }        private Guid _uid;        //La chiave primaria    public Guid UID    {        get{ return this._uid; }    }        private bool _isNew;    /*        La proprietà in sola lettura IsNew        ci permette di sapere se l'istanza        che stiamo maneggiando arriva da un         DataSource o sia una nuovo elemento    */    public bool IsNew    {        get{ return this._isNew; }    }        private string _description;    public string Description    {        get{ return this._description; }        set        {            if( value == null )            {                value = String.Empty;            }                        if( !value.Equals( this._description ) )            {                this._description = value;             }        }    }        /*        ParametersCollection (omessa per semplicità) non è che una        collection di coppia Key (String)/Value (Object) che viene         usata a mo di MOC object al fine di scambiare dati con lo         strato di factory    */    protected virtual ParametersCollection GetParameters()    {        ParametersCollection parameters = new ParametersCollection();        parameters.Add( "UID", this.UID );        parameters.Add( "Description", this.Description );                return parameters;    }        protected abstract void InsertData( ParametersCollection parameters );    protected abstract void UpdateData( ParametersCollection parameters );    protected abstract void DeleteData( ParametersCollection parameters );        public void Save()    {        /*            Nell'applicazione reale la gestione è decisamente più            complessa e comprende una serie di eventi che permettono             di manipolare dall'esterno alcuni aspetti e consento anche            di interrompere il processo di salvataggio e/o cancellazione        */        ParametersCollection parameters = this.GetParameters();        /*            Usiamo IsNew per determinare quale sia l'azione            da intraprendere per il salvataggio        */        if( this.IsNew )        {            this.InsertData( parameters );        }        else        {            this.UpdateData( parameters );        }    }        public void Delete()    {        ParametersCollection parameters = new ParametersCollection();        parameters.Add( "UID", this.UID );                this.DeleteData( parameters );    }}//// ASSEMBLY// Topics.MyApplication.Domain.dll//public class MyCustomer : MyObject{    protected override void Initialize( System.Data.IDataReader reader )    {        if( reader == null )        {            /*            L'istanza rappresenta un nuovo oggetto            quindi inizializziamo i field con i            valori di default            */            this._companyName = String.Empty;        }        else        {            this._companyName = reader.GetString( reader.GetOrdinal( "CompanyName" ) );        }    }    public MyCustomer( System.Data.IDataReader reader )        : base( reader )    {            }        public MyCustomer()        : base()    {            }        private string _companyName;    public string CompanyName    {        get{ return this._companyName; }        set        {            if( value == null )            {                value = String.Empty;            }                        if( !value.Equals( this._companyName ) )            {                this._companyName = value;             }        }    }        protected override ParametersCollection GetParameters()    {        ParametersCollection parameters = base.GetParameters();        parameters.Add( "CompanyName", this.CompanyName );                return parameters;    }        protected override void InsertData( ParametersCollection parameters )    {        /*            TODO            Solo la classe "reale" Customer conosce il sistema            per persistere/manipolare i propri dati        */    }        protected override void UpdateData( ParametersCollection parameters )    {        /*            TODO            Solo la classe "reale" Customer conosce il sistema            per persistere/manipolare i propri dati        */    }        protected override void DeleteData( ParametersCollection parameters )    {        /*            TODO            Solo la classe "reale" Customer conosce il sistema            per persistere/manipolare i propri dati        */    }} Persistence LayerE' lo strato che si occupa effettivamente di persistere ( Insert Update e Delete ) i dati, anche qui un esempio...

posted @ martedì 23 agosto 2005 15.31 | Feedback (6)

WebForms e ShowModalDialog() - intergrazione di JavaScript

Spesso e volentieri leggo sui vari NG di svariati problemi nel tentativo di integrare finestre modali all'interno di una applicazione web.Innanzitutto vorrei sottolineare che non considero la soluzione "Modale" in ambiente Web una soluzione, il flusso delle informazioni in ambiente web deve essere rivisto al fine di adeguarsi alle caratteristiche del web, i soli problemi di xBrowsing dovrebbero farci dimenticare un sacco di cose. Comunque in situazioni ben controllate, esempio tipico sono le intranet, la soluzione modale velocizza di molto lo sviluppo e mantiene l'utente "legato" (lo ritento negativo) al tradizionale sitema di imput e di browsing dei dati, classicamente "WindowsForms...

posted @ lunedì 27 dicembre 2004 16.42