Categorie
PHP

Programmare verso l’interfaccia non verso l’implementazione

Uno dei principi cardine della programmazione ad oggetti è sicuramente:

Programmare verso l’interfaccia non verso l’implementazione.
(Program to an interface, not an implementation)

Tuttavia, questo principio ci pone, un interrogativo.
Noi che sviluppiamo in PHP, che per natura è un linguaggio debolmente tipizzato, dobbiamo considerarlo valido e fondamentale come lo è per chi programma con linguaggi fortemente tipizzati? (Java piuttosto che C#)

Programmare verso l’implementazione

Programmare verso l’implementazione significa in parole povere ereditare da classi con operazioni (metodi per PHP) già implementate.
Ho già spiegato nel mio precedente articolo Ereditarietà vs Composizione quanto sia allo stesso tempo utile ma anche pericoloso utilizzare l’ereditarietà come tecnica di riutilizzo del codice.
Con l’ereditarietà siamo in grado di definire rapidamente un oggetto basandoci su uno vecchio. Ma allo stesso tempo andremo incontro a svariate conseguenze negative.

Programmare verso l’interfaccia

Quando tutte la classi implementano un’interfaccia (oppure ereditano da una classe astratta) condivideranno la sua interfaccia. I vantaggi di questo tipo di approccio non sono sempre evidenti come sembra, soprattutto per sviluppatori junior o con poca esperienza.
Anch’io all’inizio ero confuso e probabilmente sto iniziando solo ora a comprende perchè ho bisogno di loro (le interfacce).

Un’interfaccia la possiamo paragonare ad un contratto per il supporto di determinate funzionalità. Le classi che implementano un’interfaccia devono fornire i dettagli di implementazione per i membri specificati in tale interfaccia.

Programmare verso l’interfaccia significa che tutti le classi che la implementano sono in grado di aggiungere nuovi metodi ma non possono nascondere quelli dell’interfaccia o della classe astratta che ereditano.
Questo a sua volta implica che le sottoclassi saranno in grado di rispondere a tutte le richieste che la classe padre è in grado di gestire.
Il client in questo caso sarà inconsapevole della classe che effettivamente implementa, ma saprà che gli oggetti implementati saranno sempre conformi all’interfaccia.

Ma questo vale anche in PHP?

Ho iniziato l’articolo ponendomi un interrogativo.
Non v’è dubbio che in PHP sia possibile ed utile utilizzare le interfacce, tuttavia il principio (dichiarato dalla Gang of Four) dice che non si dovrebbe mai dichiarare variabili che siano istanze di classi concrete specifiche, ma bisognerebbe affidarsi ad interfacce definite in classi astratte.
In PHP tuttavia questo concetto può rimanere al quanto oscuro visto che, come detto, questo è un linguaggio debolmente tipizzato e lo sviluppatore non dichiara il tipo di variabile o funzione.
Per esempio in C# potremmo avere un’istanza come questa:

private ISomething myObj = new Something();

mentre in PHP avremo semplicemente:

$myObj = new Something();

Prima di tutto chiariamo che, per come lo intendono quelli dalla GoF, nel principio la parola interfaccia è da considerarsi non soltanto la parola chiave Interface (di PHP) ma anche le classi astratte.
Difatti Eric Gamma in un’intervista specifica che una volta che dipendiamo esclusivamente da un’interfaccia ci stiamo disaccoppiando dall’implementazione. Questo significa che l’implementazione può variare (poliformismo) e questa è da considerarsi una dipendenza sana.

Bene questo potrebbe già essere un motivo valido per applicare il principio anche in PHP, tuttavia ve n’è un’altro e cioè il fatto che PHP supporta il type hinting.
Consideriamo questo semplice esempio:

<?php
interface MyI
{
    public function sayHello ();
}

class Ita implements MyI
{
    public function sayHello()
    {
        return 'Ciao Mondo!';
    }
}

class Eng implements MyI
{
    public function sayHello()
    {
        return 'Hello World!';
    }
}

class MyClass
{
    public function __construct(MyI $concrete)
    {
        echo $concrete->sayHello();
    }
}

$concrete = new Ita;
$useMyI   = new MyClass($concrete); // Ciao Mondo!
$concrete = new Eng;
$useMyI   = new MyClass($concrete); // Hello World!

L’istanza $concrete implementa la stessa interfaccia (MyI) ma ha due differenti implementazioni.
Tuttavia poichè il type hinting punta all’interfaccia (e non alla classe concreta), si disaccoppia dall’implementazione e quindi l’istanza di MyClass accetterà qualunque implementazione.

Conclusioni

Nell’articolo ho introdotto uno dei principi fondamentali della programmazione ad oggetti, e cioè che si dovrebbe sempre sviluppare verso l’interfaccia.
Il concetto concepito per la prima volta dalla Banda di Quatto nella bibbia dei design pattern anche se coniato su linguaggi OOP fortemente tipizzati, è tuttavia a mio avviso applicabile anche in PHP, che d’altronde dalla versione 5 è ormai divenuto un linguaggio object oriented a tutti gli effetti.
E te cosa ne pensi?

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.