Utilizzo Pratico: Constructor & Property Injection
Torniamo all’esempio motivazionale d’apertura. Ora abbiamo a disposizione la nostra potente Interfaccia Logger.
Invece di ingolfare la Banca con decine di campi e switch case, diciamo alla classe Bank che le serve possedere soltanto un puntatore o una reference generica all’interfaccia Logger.
Affinché la Banca riceva la vera implementazione (es. ConsoleLogger o FileLogger), il chiamante (ad es. main) gliene inietterà una dall’esterno. Questa strategia si chiama Iniezione delle Dipendenze (Dependency Injection), e tipicamente ne esistono due versioni:
- Constructor Injection: Si inietta la dipendenza nel costruttore tramite reference. Essendo una referenza, non può essere “reseated”: la Banca terrà quello specifico logger per tutta la vita.
- Property Injection: Si inietta la dipendenza in un metodo
set_logger(...)usando i puntatori. L’approccio è più flessibile (i puntatori si possono scambiare dinamicamente), ma richiede controlli di validità extra (i puntatori possono esserenullptr).
Costruiamo l’esempio risolutivo con Property Injection.
Tramite questa architettura (unione tra l’ereditarietà dell’interfaccia e l’iniezione per composizione), la Banca diventa disaccoppiata (loosely coupled). Qualora dovesse essere rilasciato sul mercato un super efficiente RemoteDatabaseLogger, la classe Bank non andrà alterata in una singola riga di codice: basterà iniettarglielo!