mercoledì 27 marzo 2013

Singleton not immutable....

che tradotto è ... chi mi cambia il singleton da sotto le chiappe ?

Generalemte se abbiamo scritto il codice per bene, questa cosa non avviene, tuttavia potebbe succedere se e solo abbiamo commesso qualche leggerezza nella gestione della classe singleton.

Questo esempio mostra come un metodo "creato appositamente" crei un effetto davvero indesiderato.


    public class SingleInstance
    {
        private static iInstance itx = null;

        public static iInstance getInstance()
        {         
            if (SingleInstance.itx == null)
            {
                itx = new Original();
                return  itx;
            }

            return itx;            
        }

        public static void ChangeInstance()
        {            
            SingleInstance.itx = new Mock();
        }
    }

Questi i miei due oggetti che rappresenteranno il singleton

    public interface iInstance
    {
        string DoGetValue();
    }

    public class Original : iInstance
    {
        private string _value = "Orginal";
        public string DoGetValue()
        {
           return _value;
        }

    }

    public class Mock : iInstance
    {
        private string _value = "Mock";
        public string DoGetValue()
        {
           return _value;
        }
    }


Quessto è il metodo che utilizzo per effettuare il test.
Dal settimo elemento modifichiamo il nostro singleton..

        private void btnStart_Click(object sender, EventArgs e)
        {
            string v = "";

           
            for (int i = 0; i < 15; i++)
            {             
                v = Singleton.SingleInstance.getInstance().DoGetValue();

                lstEvents.Items.Add("s[" + i.ToString() + "]:" + v);
                lstEvents.Refresh();

                Thread.Sleep(100);

                if (i == 7)
                {
                    // Simuliamo 
                    // che qualcuno ci cambi le 
                    // carte in tavola 
                    Singleton.SingleInstance.ChangeInstance();
                }
            }
        } 

Morale in
v = Singleton.SingleInstance.getInstance().DoGetValue()
 
Ottengo il valore "original" fino a quando non cambio il contenuto del mio singleton..
Una variazione sul tema ... che a tutti gli effetti rende immutabile il singleton potrebbe essere questa...


Singleton.iInstance ist = Singleton.SingleInstance.getInstance();
...
... 
v = ist.DoGetValue();

L'implicazione è che l'istanza rimarrebbe strettamente legata ad una variabile senza dover mai essere reistanziata...

La secelta giusta ??? la prima ma se e solo se nessuno ti cambia da il naso il valore del singleton stesso.


Nessun commento: