I principi s.o.l.i.d. - conclusioni

in Informatica, Programmazione

I principi S.O.L.I.D – DIP

L’ultimo principio S.O.L.I.D. è il  Dependency Inversion Principle (D).

Questo principio rappresenta la separazione tra i moduli/classi di alto livello rispetto ai moduli/classi di basso livello. In pratica, tutto dovrebbe dipendere da astrazioni e non dalle loro implementazioni.

Possiamo considerare i metodi/classi di basso livello come la parte core delle nostre applicazioni: si occupano di effettuare, ad esempio,  letture/scrittura su database, accesso ai dati e persistenza su file. I moduli/classi di alto livello implementano la parte di Business Logic, ovvero la logica dell’applicazione.

Se un modulo/classe di alto livello ha una dipendenza da moduli/classi di basso livello o da qualche altra classe (conoscendone ad esempio dipendenze e relative interzioni) si dice che è fortemente accoppiato.  Questo forte accopiamento aumenta sensibilmente il rischio che la modifica dell’implementazione di una particolare classe possa richiedere modifiche anche alle classi che ne fanno uso. Per questa ragione, si devono realizzare dipendenze solo con astrazione e non con le implementazioni.

Supponiamo di voler implementare una classe che consenta di effettuare il log di un determinato messaggio:

public class ExceptionLogger  
{  
   private ILogger _logger;  
   public ExceptionLogger(ILogger aLogger)  
   {  
      this._logger = aLogger;  
   }  
   public void LogException(Exception aException)  
   {  
      string strMessage = GetUserReadableMessage(aException);  
      this._logger.LogMessage(strMessage);  
   }  
   private string GetUserReadableMessage(Exception aException)  
   {  
      string strMessage = string.Empty;  
      ....  
      ....  
      return strMessage;  
   }  
}

Come si può osservare il costruttore della classe accetta come parametro un oggetto che implementa la classe ILogger. All’interno del metodo LogException viene richiamato il metodo LogMessage della classe che implementa l’interfaccia ILogger:

public interface ILogger  
{  
   public void LogMessage(string aString);  
}

Ad esempio possiamo definire le seguenti classi :

public class DbLogger: ILogger  
{  
   public void LogMessage(string aMessage)  
   {  
      //Code to write message in database.  
   }  
}  
public class FileLogger: ILogger  
{  
   public void LogMessage(string aStackTrace)  
   {  
      //code to log stack trace into a file.  
   }  
}

In questo modo abbiamo disaccopiato la classe ExceptionLogger dalle implementazioni della classi DbLogger e FileLogger. Inoltre abbiamo realizzato un sistema modulare: una nuova classe che implementa l’interfaccia ILogger può essere utilizzata per loggare in un diverso formato/sistema.