martedì 18 dicembre 2007

Incapsulamento

Questo concetto di base ha lo scopo di "nascondere" o di "rendere inaccessibile" il funzionamento di una porzione di codice.
L'incapsulamento lo si definisce in fase di progettazione (verosimilmente nell'Analisi Tecnica) e nella maggior parte dei
casi consente di estendere il codice o di modificarlo senza coinvolgere chi lo usa.

Ora con questa spiegazione si rischia di comprendere troppo poco, ma posso garantirvi che il concetto più vicino a questo
è la programmazione a plugin.

A tale proposito è necessario un esempio, perchè come al mio solito "credo che la pratica sia a volte molto più esplicativa
della teoria".

Supponiamo di trovarci in un concessionario d'auto pronti a richiedere il nostro preventivo...
(10 anni fa ci avrebbero dato in mano una Brochure e raccontato tante belle cose, oggi in qualche concessionario le cose
sono un po' diverse).
Il venditore ci mostrà a video una serie di opzioni, le nostre scelte implicheranno poi quanto sarà realmente realizzato.

A questo punto ci spostiamo nel sorgente di quello che stiamo guardando, per meglio comprendere che cosa vuol dire
incapsulamento.

La casa produttrice del software per la personalizzazione di un veicolo, ha pensato in grande supponendo che agli inizi
avrebbero prodotto due tipi di veicolo, ipotizzando però di poter arrichire la loro produzione in futuro.

Hanno studiato quindi una serie di modelli che "universalmente" o quasi potessero descrivere le caratteristiche base
di un veicolo e ne venne fuori questo:

//
// interfaccia per il motore
//
public interface IMotore
{
int Cilindri {get;}
float Potenza { get; }
bool Turbina { get; }
Rectangle Ingombro { get; }

void Accendi();
void Spegni();
void Frena();
void Accelera();
}

//
// interfaccia per la trazione
//
public interface ITrazione
{
int Rapporti { get; set; }
int posizione { get; set; }

void AumentaMarcia();
void DecrementaMarcia();
void Folle();
void RetroMarcia();
}

//
// interfaccia per gli allestimenti
//
public interface IAllestimenti
{
bool InterniInPelle { get; set; }
bool InterniInEcoPelle { get; set; }
bool InterniInTessuto { get; set; }
bool InterniInTessuto_Pelle { get; set; }
bool InterniInTessuto_EcoPelle { get; set; }
bool FinitureAlluminio { get; set; }
bool FinitureLegno { get; set; }
bool FinitureRadica { get; set; }
bool FinitureLaccatoLucido { get; set; }
bool FinitureLaccatoOpaco { get; set; }
bool FinitureSatinato { get; set; }
bool LettoreCD { get; set; }
bool LettoreDVD { get; set; }
bool Navigatore { get; set; }
bool Dolby5 { get; set; }
bool Dolby7 { get; set; }
int Airbags { get; set; }
}


//
// classe del veicolo
//
public class Veicolo
{
public IMotore Motore;
public ITrazione Trazione;
public IAllestimenti Allestimenti;

//
// molto altro ancora...
//
}

Ancora una volta ci tengo a precisare che si tratta di esempi che potrebbero naturalmente non rappresentare
la pura realtà, e lo spero in parte.

A questo punto alla società sarebbe bastato realizzare tante librerie (esterna a quella di base) in cui
realizzare gli elementi del veicolo.

E quindi furono realizzate le prime due motorizzazioni:

public class MotorizzazioneBase : IMotore
{

#region IMotore Members

public int Cilindri
{
get { return 4; }
}

public float Potenza
{
get { return 78.5f;}
}

public bool Turbina
{
get { return false;}
}

public Rectangle Ingombro
{
get { return new Rectangle(0, 0, 200, 90);}
}

public void Accendi()
{
// quanto necessario per accendere
// inizia a far fluire il carburante
// invia scintilla a spinterogeno..

}

public void Spegni()
{
// quanto necessario per spegnere
//
}

public void Frena()
{
// prima che sia troppo tardi!
}

public void Accelera()
{
// Se no arrivi tardi...
}

#endregion
}

public class MotorizzazioneSport : IMotore
{

#region IMotore Members

public int Cilindri
{
get { return 6; }
}

public float Potenza
{
get { return 95.7f; }
}

public bool Turbina
{
get { return true; }
}

public Rectangle Ingombro
{
get { return new Rectangle(0, 0, 230, 90); }
}

public void Accendi()
{
// inizia a far fluire il carburante
// invia scintilla a spinterogeno..

}

public void Spegni()
{
// quanto necessario per spegnere
}

public void Frena()
{
// prima che sia troppo tardi!
}

public void Accelera()
{
// Se no arrivi tardi...
}

#endregion
}

A questo punto tutta la logica ( o le proprietà ) appartengono tutte ad una libreria, mentre la presentazione
dei dati risiede in un altra...

A tal proposito è possibile comprendere che variando i valori, il comportamento di MotorizzazioneSport, nella
classe Veicolo non saranno necessari interventi e per altro Veicolo non avrà precezione di cio' avviene all'interno
di MotorizzazioneSport.

Nessun commento: