Treci la conținutul principal

Respectă promisiunea

Principiul substituției Liskov spune: oriunde codul așteaptă o interfață, fiecare implementare a acelei interfețe trebuie să funcționeze corect. O implementare care se potrivește tehnic, dar se comportă greșit — aruncă erori, nu face nimic, minte — strică orice funcție care s-a încrezut în interfață.

O interfață este o promisiune. fly() promite zborul. O clasă care implementează fly() prăbușindu-se a semnat un contract pe care nu îl poate respecta.


Un înlocuitor care încalcă înțelegerea

Interfața Bird promite fly(). Vrăbiile se țin de cuvânt. Pinguinii sunt și ei păsări — așa că pare firesc să implementezi interfața... aruncând o eroare, pentru că pinguinii nu pot zbura.

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

Pinguinul care strică spectacolul

airShow se încrede în interfață și apelează fly() pe fiecare pasăre. Vrabia își face numărul; pinguinul aruncă o eroare și oprește spectacolul chiar acolo (blocul try/catch doar îndulcește aterizarea, ca să putem afișa mesajul).

Prompt
Scrie un program TypeScript 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 eroare, pentru că pinguinii nu pot zbura. O funcție airShow apelează fly pe fiecare pasăre; folosește try/catch în jurul spectacolului pentru a afișa mesajul de eroare atunci când intră în scenă pinguinul.
Ieșire: program TypeScript și rezultatul capturat

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: trimiterea unui pinguin către airShow nu mai este o prăbușire în timpul rulării programului — este o eroare de tip, raportată înainte ca programul să pornească.

Fiecare tip îș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
Repară încălcarea Liskov în TypeScript împărțind promisiunile: o interfață Flyer cu fly și o interfață Swimmer cu swim. Sparrow implementează Flyer, Penguin implementează Swimmer. Scrie airShow pentru zburătoare și poolShow pentru înotătoare și rulează-le pe amândouă, astfel încât fiecare clasă să apară doar acolo unde promisiunea ei este valabilă.
Ieșire: program TypeScript și rezultatul capturat
Every type keeps its promise

Orice Flyer se poate alătura

Răsplata interfețelor oneste: o nouă clasă Eagle se alătură spectacolului aerian fără niciun risc — orice implementează Flyer chiar zboară, așa că airShow nu are nevoie să se îndoiască de datele primite.

Prompt
Extinde exemplul cu interfața Flyer din TypeScript adăugând o nouă clasă Eagle și rulează un spectacol aerian cu mai multe zburătoare, arătând că orice implementare onestă a lui Flyer poate fi substituită în siguranță.
Ieșire: program TypeScript și rezultatul capturat