PHP: SOLID [L] Zasada podstawienia Liskov
To trzecia zasada SOLID „Zasada podstawienia Liskov„. Polega na podstawieniu metod klasy dziedziczącej w miejsce klasy bazowej.
Wstęp
Wypada troszkę temat rozwinąć. Klasa dziedzicząca powinna być w 100% zgodna z klasą bazową. Nie powinny mieć miejsca sytuacje, gdy klasa bazowa posiada np. metodę „sell„, a dziedzicząca klasa nie powinna niczego sprzedawać.
Przykład
Przypuśćmy, że nasz program polega na oferowaniu różnej maści raportów. Część z nich można zakupić, natomiast inne są dodawane wyłącznie w gratisie.
Klasa każdego raportu dziedziczy z bazowej o nazwie „Report„
Class ReportValuation extends Report { ... }
Class ReportExpert extends Report { ... }
Klasa „Report” posiada różne metody z których klasy dziedziczące oczywiście korzystają.
Pojawiła się w klasie bazowej również metoda o nazwie „sell„, ale nasz raport eksperta nie może zostać sprzedany, ponieważ jest dodawany jako bonus do raportu wyceny.
W opisanej powyżej sytuacji, powinniśmy nadpisać raport z klasy bazowej:
Class ReportExpert extends Report { public function sell() { throw new \Exception('Error'); } }
Rozwiązanie przedstawione powyżej to zapewne pierwsza Wasza myśl. Z jednej strony jest to rozwiązanie prawidłowe, bowiem zabezpieczamy program przed sprzedażą raportu który sprzedany zostać nie może. Posiada np. cenę równą „0.00” a to spowoduje błąd przy inicjacji płatności u operatora.
Rozwiązanie problemu
Według trzeciej zasady SOLID, w klasie bazowej nie możemy umieścić metody „sell” bowiem nie wszystkie klasy dziedziczące są w stanie z niej skorzystać. W naszym wypadku skorzystanie z metody „sell” klasy „ReportExpert” zwrócimy wyjątek zamiast inicjacji płatności.
Aby zgodnie z Zasadą Podstawiania Liskov rozwiązać nasz problem, powinniśmy usunąć metodę „sell” z klasy bazowej, a sprzedaż raportów rozwiązać na przykład za pomocą kompozycji.
Zakończenie
Według autora Zasady Podstawiania powinniśmy doprowadzić do sytuacji takiej, że w każdym miejscu wywołania klasy dziedziczącej, powinniśmy móc podstawić klasę bazową.
Klasa dziedzicząca nie powinna zmieniać metod klasy bazowej, a jedynie je rozszerzać.