Refactoring: sostituire lo switch con il polimorfismo

datedomenica 31 ottobre 2010 alle 10.36  - posted by Manuel Scapolan in C#

Lo switch viene spesso utilizzato assieme ad un enumerativo per specificare porzioni di codice da eseguire in base al valore di una determinata variabile. L'utilizzo di tale costrutto rende però il nostro codice rigido e poco mantenibile perché all'aggiunta di un nuovo valore siamo costretti ad aggiornare sia l'enumerativo che lo switch.
Vediamo allora come con un refactoring object-oriented possiamo sostituire lo switch per rendere il nostro codice più flessibile, mantenibile e pulito.

Nell'esempio seguente abbiamo creato una classe MSOfficeLicence con un metodo Price che tramite uno switch ritorna il prezzo di una licenza Office in base al tipo (Home o Business):

public class MSOfficeLicence
{
  public enum LicenceType
  { 
   Home = 0,
   Business = 1
  }
 
  private MSOfficeLicence.LicenceType _type;
  public MSOfficeLicence.LicenceType Type { get { return _type; } }
 
  public MSOfficeLicence(MSOfficeLicence.LicenceType type)
  {
   this._type = type;
  }
 
  public decimal Price()
  {
   switch (_type)
   { 
     case LicenceType.Home:
       return (decimal)99.90;
     case LicenceType.Business:
       return (decimal)180.90;
     default:
       throw new ArgumentNullException("Type not valid");
   }
  }
}

Proviamo ad applicare il polimorfismo e quindi rendiamo la classe MSOfficeLicence e il metodo Price astratti e creiamo una classe derivata per ogni tipo di licenza:

public abstract class MSOfficeLicence
{
  public abstract decimal Price();
}
  
public class MSOfficeHome : MSOfficeLicence
{
  public override decimal Price()
  {
    return (decimal)99.90;
  }
}
  
public class MSOfficeBusiness : MSOfficeLicence
{
  public override decimal Price()
  {
    return (decimal)180.90;
  }
}

Ecco che tolto lo switch possiamo aggiungere nuovi tipi di licenza semplicemente creando una nuova derivata che esegue l'override del metodo Price. La logica del codice client deciderà quindi quale licenza istanziare magari tramite una factory o semplicemente tramite dependency injection:

MSOfficeLicence Licence = new MSOfficeHome();
Console.Write(Licence.Price());

Nota: I prezzi sono solo a titolo di esempio :-)

Commenti chiusi

About me

manuel scapolanSono un consulente informatico. Nel 2004 terminati gli studi in Ingegneria Informatica (1° livello), ho iniziato come freelance collaborando con una ditta di consulenza informatica ed una agenzia di marketing e comunicazione nello sviluppo di applicazioni web. Attualmente divido il lavoro di sviluppatore e progettista web con attività di formazione nel settore della programmazione.
View Manuel Scapolan's profile on LinkedIn

Follow me on Follow manuelscapolan on Twitter
Member of:
innova

Calendario


<<  maggio 2012  >>
lumamegivesado
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Disclaimer

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati mediante:
creative commons
Attribuzione: Non commerciale
Condividi allo stesso modo. R.2.5

Books (a bit more about my library)

Domain Driven Design - Eric Evans Applying Domain-Driven Design and Patterns - Jimmy Nilsson Refactoring to Patterns - Joshua Kerievsky Design Patterns -  Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides Code Complete Second Edition - Steve McConnell Patterns of Enterprise Application Architecture - Martin Fowler Agile Principles, Patterns, and Practices in C# - Robert C. Martin xUnit Test Patterns - Gerard Meszaros Refactoring - Martin Fowler CLR via C# Second Edition - Jeffrey Richter Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries - Krzysztof Cwalina, Brad Abrams Don't make me think! - Steve Krug Bulletproof Ajax - Jeremy Keith

Manuel Scapolan Copyright © 2007 - 2010 - Tutti i diritti riservati - Powered by BlogEngine.NET 1.5.0.7 - silk icons by famfamfam - Time CET