S.O.L.I.D – 3. Zasada podstawienia Liskov (L – Liskov substitution)
SOLID – Zasada podstawienia Liskov – to już trzecia z poznanych przez nas wytycznych. Nazwa tej reguły pochodzi od nazwiska amerykańskiej programistki Barbary Liskov, która razem z Janette Wing sformułowała ją we wspólnej pracy pt. „A Behavioral Notion of Subtyping„. Mówi ona o tym, aby w miejscu klasy bazowej można było zawsze użyć dowolnej klasy pochodnej. Kod powinien poprawnie współpracować z klasą jak i wszystkimi podklasami. Zasadę tę najlepiej wytłumaczyć na przykładzie. Kod w PHP:
class Weapon
{
public function hit()
{
//use weapon to hit
}
public function shoot()
{
//use weapon to shoot
}
}
class Sword extends Weapon {}
class Bow extends Weapon {}
Zobaczmy, że w powyższym kodzie mamy niezgodność – o ile łukiem (klasa Bow) możliwe jest zarówno strzelanie (metoda shoot()) oraz uderzenie (metoda hit()), o tyle dla miecza (klasa Sword) nielogiczne jest użycie metody shoot(). Aby rozwiązać ten problem można posłużyć się użyciem interfejsów lub też użyciem klas pośrednich:
// na potrzeby przykładu załóżmy, że każdą bronią można w pewien sposób uderzyć
class Weapon
{
public function hit()
{
//use weapon to hit
}
}
class WeaponCanShoot extends Weapon
{
public function shoot()
{
//use weapon to shoot
}
}
class WeaponCantShoot extends Weapon {}
class Sword extends WeaponCantShoot {}
class Bow extends WeaponCanShoot {}
Teraz nie ma możliwości, aby instancja klasy Sword miała możliwość strzelania, ponieważ poprzez łańcuch dziedziczenia ta metoda jest niedostępna. Dzięki temu unikamy braku logiki i powstania błędu. Ponadto obiekt klasy pochodnej można użyć w miejscu klasy bazowej.
Z pewnością przedstawiony przykład jest dość abstrakcyjny i bardzo prosty. Jednak chodziło tutaj przede wszystkim właśnie o proste i szybkie wytłumaczenie zasady działania omawianej reguły.
Dziękuję za zapoznanie się artykułem dotyczącym pierwszej wytycznej SOLID – Zasada podstawienia Liskov.
Zapraszam do kolejnego artykułu. Pochylimy się nad kolejną wytyczną jaką jest zasada segregacji interfejsów.