Treci la conținutul principal

Respectă promisiunea

Principiul substituției Liskov spune: oriunde codul așteaptă o interfață, fiecare clasă care o implementează trebuie să funcționeze corect. O implementare care se potrivește formal, dar se comportă prost — aruncă excepții, nu face nimic, minte — strică orice funcție care s-a încrezut în interfață.

O interfață este o promisiune. fly() promite zbor. O clasă care implementează fly() aruncând o excepție a semnat un contract pe care nu îl poate respecta.


Un substitut care încalcă înțelegerea

Interfața Bird promite fly(). Vrăbiile se țin de promisiune. Pinguinii sunt și ei păsări — așa că pare firesc să implementeze interfața... cu un throw, pentru că pinguinii nu pot zbura.

Acum airShow, care funcționează pentru orice pasăre onestă, se prăbușește pe un pinguin. Eroarea nu este în airShow — este în substitutul care a încălcat promisiunea.

Pinguinul care prăbușește spectacolul

airShow se încrede în interfață și apelează fly() pe fiecare pasăre. Vrabia își face numărul; pinguinul aruncă o excepție și doboară tot spectacolul (blocul try/catch doar atenuează căderea, pentru a afișa mesajul).

Prompt
Scrie un script PHP care arată o încălcare a substituției Liskov: o interfață Bird cu o metodă fly, o clasă Sparrow care zboară și o clasă Penguin a cărei metodă fly aruncă o excepție RuntimeException, pentru că pinguinii nu pot zbura. O funcție airShow apelează fly pe fiecare pasăre; folosește try/catch pentru a afișa mesajul de eroare atunci când intră în scenă pinguinul.
Ieșire: script PHP

Separă promisiunile

Soluția: promite doar ceea ce este adevărat. Împarte promisiunea prea largă în Flyer și Swimmer. Vrabia implementează Flyer, pinguinul implementează Swimmer — și nicio clasă nu semnează un contract pe care nu îl poate respecta.

Partea cea mai bună este cine prinde acum greșeala: airShow are tipul declarat Flyer, deci airShow(new Penguin()) nu trece verificarea de tip — PHP oprește apelul cu un TypeError înainte ca vreo pasăre să intre în scenă, iar un analizor static semnalează linia chiar înainte ca codul să ruleze.

Fiecare clasă își respectă promisiunea

airShow acceptă Flyer, poolShow acceptă Swimmer. Fiecare animal apare doar acolo unde promisiunea lui este valabilă — substituția este sigură prin construcție.

Prompt
Corectează încălcarea principiului Liskov în PHP prin separarea promisiunilor: o interfață Flyer cu fly și o interfață Swimmer cu swim. Sparrow implementează Flyer, Penguin implementează Swimmer. Scrie airShow pentru zburători și poolShow pentru înotători și rulează-le pe amândouă, astfel încât fiecare clasă să apară doar acolo unde promisiunea ei este valabilă.
Ieșire: script PHP
Every class keeps its promise

Orice Flyer se poate alătura

Câștigul interfețelor oneste: o nouă clasă Eagle se alătură spectacolului aerian fără niciun risc — orice implementează Flyer zboară cu adevărat, deci airShow nu trebuie niciodată să se îndoiască de datele primite.

Prompt
Extinde exemplul PHP cu interfața Flyer printr-o nouă clasă Eagle și rulează un spectacol aerian cu mai mulți zburători, arătând că orice implementare onestă a interfeței Flyer poate fi substituită în siguranță.
Ieșire: script PHP