Articoli di programmazione

Come evitare gli Switch-Case nel nostro codice

Switch-Case è una struttura di controllo molto utilizzata ma poco manutenibile; scopriamo come implementare una logica più flessibile

How-to-learn-Programming.jpg
Tutti conosciamo ed usiamo Switch-Case nel nostro codice e più diventiamo esperti, più ci accorgiamo che Switch-Case ci costringe a scrivere lunghi metodi poco eleganti, e soprattutto poco manutenibili perchè ogni opzione necessita di una modifica al codice con relativa ricompilazione e rilascio. Inoltre la logica applicativa deve in qualche modo risiedere nello Switch-Case stesso e questo accentra molte responsabilità che l'oggetto che lo contiene probabilmente non dovrebbe avere.

Vediamo quindi come migliorare questo listato in qualcosa di disaccoppiato e quindi maggiormente flessibile e manutenibile.

switch(myVar)
{
case "1":
internalObject.Send("one");
break;
case "2":
internalObject.Send("two");
break;
}

Possiamo usare un pattern #Strategy per trasformare ciascuna opzione del nostro #Swicth-Case in una strategia ben isolata da richiamare all'occorrenza.
Nella sua accezione più semplice, in C# il pattern #Strategy può essere declinata in un sotto-pattern che si basa su un Dictonary generico a cui faremo corrispondere l'esecuzione del comando in base ad una stringa di input.
Ecco di cosa si tratta:

var d = new Dictionary<string, Action>();
d.Add("1", () => internalObject.Send("one"));
d.Add("2", () => internalObject.Send("two"));

// execute the Command
var input = "1"; // this can come from a SelectBox or an Input
var result = d[input]();

Potrebbe essere opportuno verificare che l'azione desiderata sia inclusa nel #Dictonary. E' quindi possibile scrivere in fase di esecuzione una cosa del genere per gestire eventuali mancanze:

Action action = null;
if (d.TryGetValue(input, out action))
action();
else
Console.WriteLine("Oooops I've not found the option you selected!");


Se è necessario ottenere un risultato da #Switch-Case anziché una semplice esecuzione di un metodo, è possibile usare Func invece di #Action. Ecco quindi un listato alternativo:

var d = new Dictionary<string,Func<string>>();
d.Add("1", () => {return "One";});
d.Add("2", () => {return "Two";});

var input = "1";
var r = (d.ContainsKey(input))? d[input]() : "Option not found";
Console.WriteLine(r);


#programmazione #csharp #tips