Principio della Sostituzione di Liskov, terzo principio S.O.L.I.D.

principio di liskov
Formazione

Le classi figlie non dovrebbero mai influire o modificare le definizioni del tipo della classe genitore.

Il concetto di questo principio è stato introdotto da Barbara Liskov in un keynote della conferenza del 1987 e successivamente pubblicato in un articolo insieme a Jannette Wing nel 1994. La loro definizione originale è la seguente:

Sia q (x) una proprietà dimostrabile su oggetti x di tipo T. Allora q (y) dovrebbe essere dimostrabile per oggetti y di tipo S dove S è un sottotipo di T.

Successivamente, con la pubblicazione dei principi SOLID di Robert C.Martin nel suo libro Agile Software Development, Principles, Patterns, and Practices e poi ripubblicata nella versione C # del libro Agile Principles, Patterns, and Practices in C #, la definizione divenne noto come principio di sostituzione di Liskov.

Questo ci porta alla definizione data da Robert C. Martin: I sottotipi devono essere sostituibili con i loro tipi di base.

Più semplicemente, una sottoclasse dovrebbe sovrascrivere i metodi della classe genitore in un modo che non interrompe la funzionalità dal punto di vista di un cliente. Ecco un semplice esempio per dimostrare il concetto.

class Vehicle {

    function startEngine() {

        // Default engine start functionality

    }

 

    function accelerate() {

        // Default acceleration functionality

    }

}

Data una classe Veicolo – può essere astratta – e due implementazioni:

class Car extends Vehicle {

    function startEngine() {

        $this->engageIgnition();

        parent::startEngine();

    }

 

    private function engageIgnition() {

        // Ignition procedure

    }

}

 

class ElectricBus extends Vehicle {

    function accelerate() {

        $this->increaseVoltage();

        $this->connectIndividualEngines();

    }

 

    private function increaseVoltage() {

        // Electric logic

    }

 

    private function connectIndividualEngines() {

        // Connection logic

    }

}

class Driver {

    function go(Vehicle $v) {

        $v->startEngine();

        $v->accelerate();

    }

}

Una classe client dovrebbe essere in grado di utilizzare entrambi, se può utilizzare Vehicle.

Il che ci porta a una semplice implementazione del Template Method Design Pattern come l’abbiamo utilizzato nel OCP.

Potrebbe interessarti anche il secondo principio SOLID: https://bloginnovazione.it/open-closed-secondo-principio-s-o-l-i-d/3906/

Sulla base della nostra precedente esperienza con il principio Open / Closed, possiamo concludere che il principio di sostituzione di Liskov è in stretta relazione con l’OCP. Infatti, “una violazione di LSP è una violazione latente di OCP” (Robert C. Martin), e il Template Method Design Pattern è un classico esempio di rispetto e implementazione di LSP, che a sua volta è una delle soluzioni per rispettare anche OCP .

Esempio di violazione LSP

class Rectangle {

    private $topLeft;

    private $width;

    private $height;

 

    public function setHeight($height) {

        $this->height = $height;

    }

 

    public function getHeight() {

        return $this->height;

    }

 

    public function setWidth($width) {

        $this->width = $width;

    }

 

    public function getWidth() {

        return $this->width;

    }

}

Iniziamo con una forma geometrica di base, un rettangolo. È solo un semplice oggetto dati con setter e getter per larghezza e altezza. Immagina che la nostra applicazione funzioni e sia già distribuita su diversi client. Ora hanno bisogno di una nuova funzionalità. Devono essere in grado di manipolare i quadrati.

Nella vita reale, in geometria, un quadrato è una particolare forma di rettangolo. Quindi potremmo provare a implementare una classe Square che estende una classe Rectangle. Si dice spesso che una classe figlia è una classe genitore, e anche questa espressione è conforme a LSP, almeno a prima vista.

class Square extends Rectangle {

    public function setHeight($value) {

        $this->width = $value;

        $this->height = $value;

    }

 

    public function setWidth($value) {

        $this->width = $value;

        $this->height = $value;

    }

}

Un quadrato è un rettangolo con larghezza e altezza uguali e potremmo eseguire una strana implementazione come nell’esempio precedente. Potremmo sovrascrivere entrambi i setter per impostare sia l’altezza che la larghezza. Ma in che modo ciò influirà sul codice client?

class Client {

    function areaVerifier(Rectangle $r) {

        $r->setWidth(5);

        $r->setHeight(4);

        if($r->area() != 20) {

            throw new Exception(‘Bad area!’);

        }

        return true;

    }

}

È concepibile avere una classe client che verifica l’area del rettangolo e genera un’eccezione se è sbagliato.

function area() {

    return $this->width * $this->height;

}

Ovviamente abbiamo aggiunto il metodo sopra alla nostra classe Rectangle per fornire l’area.

class LspTest extends PHPUnit_Framework_TestCase {

    function testRectangleArea() {

        $r = new Rectangle();

        $c = new Client();

        $this->assertTrue($c->areaVerifier($r));

    }

}

E abbiamo creato un semplice test inviando un oggetto rettangolo vuoto al verificatore di area e il test viene superato. Se la nostra classe Square è definita correttamente, inviarla all’areaVerifier () del Cliente non dovrebbe interrompere la sua funzionalità. Dopo tutto, un quadrato è un rettangolo in tutto il senso matematico. Ma è la nostra classe?

function testSquareArea() {

    $r = new Square();

    $c = new Client();

    $this->assertTrue($c->areaVerifier($r));

}

Quindi, la nostra classe Square non è dopotutto un Rettangolo. Infrange le leggi della geometria. Fallisce e viola il principio di sostituzione di Liskov.

Ercole Palmeri

CV Ercole Palmeri

Nessun commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

marketing google trends
Formazione
Come usare Google Trends per fare marketing in tempo reale

Una delle maggiori difficoltà incontrate nel 2020 dalle aziende è stato capire in quali settori merceologici diversificare il proprio business: infatti gran parte dei settori industriali ha subìto pesanti contraccolpi rendendo quasi impossibile alle aziende la loro penetrazione, soprattutto in qualità di nuovo player.   Pochissimi i settori del manifatturiero …

Solid figure geometriche solide
Formazione
SOLID cosa sono i 5 principi della programmazione a oggetti

S.O.L.I.D. è un acronimo, riferito ai cinque principi di progettazione orientata agli oggetti (OOD o OOP). Sono delle linee guida che gli sviluppatori possono utilizzare per creare software in modo semplice da gestire, mantenere ed estendere. La comprensione di questi concetti ti renderà uno sviluppatore migliore e ti consentirà di …

innovazione significato
Metodi
4 passi (pratici) per dare vita ad un’innovazione

Non è un segreto: la pandemia da coronavirus ha cambiato la vita di moltissimi. Da un giorno all’altro ci siamo ritrovati senza lavoro o semplicemente con la necessità di fare qualcosa di nuovo, di dare vita ad un’innovazione. In questo articolo vogliamo perciò aiutarti, consigliandoti 4 semplici passi per dare …