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 — declanșează panic, nu face nimic, minte — strică orice funcție care s-a încrezut în interfață.

O interfață este o promisiune. Fly() promite zborul. Un tip care implementează Fly() prăbușind programul 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 cuvânt. Pinguinii sunt și ei păsări — așa că pare firesc să implementezi interfața... cu un panic, pentru că pinguinii nu pot zbura.

Acum airShow, care funcționează pentru orice pasăre cinstită, se prăbușește la un pinguin. Problema 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() pentru fiecare pasăre. Vrabia își face numărul; pinguinul declanșează panic și doboară tot programul (recover doar îndulcește aterizarea, ca să putem afișa mesajul).

Prompt
Scrie un program Go care arată o încălcare a principiului substituției Liskov: o interfață Bird cu o metodă Fly, un Sparrow care zboară și un Penguin a cărui metodă Fly declanșează panic, pentru că pinguinii nu pot zbura. O funcție airShow apelează Fly pentru fiecare pasăre; folosește recover în main pentru a afișa mesajul de prăbușire atunci când intră în scenă pinguinul.
Ieșire: program Go ș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 niciun tip nu semnează un contract pe care nu îl poate respecta.

Partea cea mai bună este cine prinde acum greșeala: transmiterea unui pinguin către airShow nu mai este o prăbușire la execuție — este o eroare de compilare. Programul nici măcar nu se construiește.

Fiecare tip își respectă promisiunea

airShow acceptă Flyer, poolShow acceptă Swimmer. Fiecare animal apare doar acolo unde promisiunea lui este adevărată — substituția este sigură prin însăși construcția codului.

Prompt
Repară încălcarea Liskov în Go î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 tip să apară doar acolo unde promisiunea lui este adevărată.
Ieșire: program Go și rezultatul capturat
Every type keeps its promise

Orice Flyer se poate alătura

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

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