Principio di sostituzione di Liskov

1

Sto cercando di avvolgere la mia mente su un Principio di sostituzione di Liskov e mi sono imbattuto in questo articolo.

SOLID Class Design: The Liskov Substitution Principle

In questo articolo, l'autore fornisce un esempio di Flightless Bird (Penguin) per estendere una classe generale Bird che sarebbe chiusa per "aggiunta al nuovo tipo di uccelli".

Non sta violando il Principio Aperto / Chiuso? O sta definendo una sottoclasse permessa nel mantenimento per Open / Closed con il principio di sostituzione di Liskov?

    
posta Ayman Arif 26.09.2018 - 08:45
fonte

2 risposte

7

Questo è un articolo molto interessante.

Principio di apertura / chiusura

La definizione di una sottoclasse non infrange il principio di apertura / chiusura , poiché significa "< em> apri per estensione / chiudi per modifica ". Quindi:

  • Si può perfettamente aggiungere Penguin sottoclasse per estendere Bird
  • Ma cambiare l'interfaccia della classe Bird per aggiungere il supporto per gli uccelli che non possono volare è una modifica definitiva.

La classe Bird è stata viziata dall'inizio

Che cosa ci mostra l'esempio? Un caso molto pratico su come gestire un design imperfetto. E se il design non è praticabile, devi cambiarlo.

La classe Bird era difettosa sin dall'inizio, perché non teneva conto del fatto che ci sono uccelli che non possono volare, sia l'intera classe Penguin o una singola istanza di injuredBird .

La classe è ancora più difettosa di quanto sembri. Poiché tutti gli uccelli hanno intervalli di altitudine: martin pescatori possono avere un'altitudine leggermente negativa sotto l'acqua. E nessun uccello non può volare nella stratosfera: alcune specie possono volare fino a 11.300 km, mentre altre sono limitate a 8.000. E Penguins sono limitati tra 0 e 0 sopra il terreno (in realtà possono immergersi, quindi è consentita anche l'altitudine negativa.

Principio di sostituzione di Liskov in tutto questo?

Osservando il codice di esempio, l'aggiunta di Penguin all'originale Bird non è in effetti un problema in base al LSP , perché non viene fatta alcuna promessa sul risultato di setAltitude() .

L'LSP ci dice che:

    Le precondizioni
  • non possono essere rafforzate.
  • Le postcondizioni
  • non possono essere indebolite. Non si sostiene che l'altitudine sarà impostata sul valore fornito, quindi non c'è alcun indebolimento. Se il post-condono è che il nuovo valore dell'altitudine è compreso tra 0 e il valore fornito, l'estensione corrisponderà alle regole lasciando l'altitudine invariata. Btw.us, questa post-condizione consentirebbe anche injuredBird e newBornBird .
  • Gli invarianti
  • devono essere preservati.
  • il vincolo cronologico deve essere garantito Ciò implica che lo stato e il comportamento di Bird dipendono solo dall'utilizzo della sua interfaccia definita. Ad esempio, Penguin non potrebbe avere nessun altro metodo che cambierebbe l'altitudine senza fare affidamento su setAltitude() .
risposta data 26.09.2018 - 09:15
fonte
1

Is it not violating the Open/Closed Principle or defining a sub-class is allowed in maintaining for Open/Closed and Liskov-Substitution Principle?

Il principio Aperto / Chiuso deve essere compreso in un contesto in cui il progetto è già corretto, cioè privo di altri difetti OO. Se hai modellato un problema nel modo corretto, l'OCP ti dice che puoi estendere una classe sottoclassi, ma non dovresti modificarla.

Ciò che l'articolo ci dice è che il problema non è stato modellato correttamente in primo luogo. La posta in gioco è che dietro la maggior parte delle violazioni LSP si nasconde una proprietà implicita - qui, è la post-condizione :

The bird's altitude must change after you've called setAltitude()

L'aggiunta di una classe FlightfulBird in più risolve questo rendendo evidente la proprietà (almeno concettualmente - avremmo potuto renderla concretamente corretta con una post-condizione esplicita). Ma non ha nulla a che vedere con la conformità al principio Open / Closed, è solo un modo per ottenere il design giusto, prima che l'OCP entri in gioco.

    
risposta data 26.09.2018 - 09:42
fonte