Tutorial

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

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;

    }

 

Articoli correlati

    public function getHeight() {

Newsletter sull’Innovazione
Non perderti le notizie più importanti sull'Innovazione. Iscriviti per riceverle via e-mail.

        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

Newsletter sull’Innovazione
Non perderti le notizie più importanti sull'Innovazione. Iscriviti per riceverle via e-mail.

Articoli recenti

Creating Innovation Opportunities for the Energy Sector

Alberta Innovates annuncia nuovi finanziamenti attraverso il programma Digital Innovation in Clean Energy  (DICE). Sono disponibili 2,5 milioni di dollari in finanziamenti da…

2 Dicembre 2023

Innovazione, arriva il chip che fa i ‘conti’ con la luce

Il wireless ottico potrebbe non avere più ostacoli. Studio del Politecnico di Milano con Scuola Superiore Sant’Anna di Pisa, e…

2 Dicembre 2023

Innovazione nell’organizzazione del Lavoro: EssilorLuxottica introduce le ‘settimane corte’ in fabbrica

In un’epoca di grandi trasformazioni economiche e sociali emerge l’urgenza di ridisegnare nuovi modelli organizzativi delle aziende per guidare il…

2 Dicembre 2023

EarlyBirds riconosciuta tra le migliori startup australiane di software nel 2023, pioniera dell’innovazione aperta e dell’intelligence industriale in tutti i settori

EarlyBirds , la piattaforma australiana di Open Innovation e Industry Intelligence, si distingue come innovatore leader tra le startup australiane di…

2 Dicembre 2023

Intelligenza artificiale in sanità, a Palermo il 3° meeting AIIC

Quale contributo effettivo può dare e sta già dando l’Intelligenza artificiale all’ambito delle cure e della sanità italiana? Questa è…

2 Dicembre 2023

Summit Lightspeed: svelare il futuro del commercio e dell’innovazione

Lightspeed Commerce Inc. ha recentemente ospitato l'edizione 2023 del Lightspeed Summit, "Oxygen".  Il vertice di tre giorni a Montreal ha riunito…

1 Dicembre 2023

Amazon lancia nuovi corsi di formazione gratuiti sull’intelligenza artificiale generativa

L'iniziativa "AI Ready" di Amazon, offre lezioni online per sviluppatori e altri professionisti tecnici, nonché per studenti delle scuole superiori…

29 Novembre 2023

Cos’è l’intelligenza artificiale generativa: come funziona, vantaggi e pericoli

L’intelligenza artificiale generativa è l’argomento di discussione tecnologico più caldo del 2023. Cos’è l’intelligenza artificiale generativa, come funziona e di…

28 Novembre 2023

Rainbow, la soluzione di telefonia e collaborazione basata su cloud di Alcatel-Lucent Enterprise, ottiene la prestigiosa certificazione CSPN da ANSSI

Alcatel-Lucent Enterprise è orgogliosa di annunciare che la sua piattaforma di collaborazione, Rainbow™ by Alcatel-Lucent Enterprise ha ottenuto la Certificazione…

28 Novembre 2023

BYD arriva a quota 6 milioni di veicoli a nuova energia prodotti

BYD ha centrato un risultato storico: sei milioni di veicoli a nuova energia usciti dalla catena di montaggio dello stabilimento…

28 Novembre 2023