Zasada podstawienia Liskov

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacja, szukaj

W programowaniu obiektowym zasada podstawienia Liskov (ang. Liskov substitution principle) mówi, że:

Funkcje które używają wskaźników lub referencji do klas bazowych, muszą być w stanie używać również obiektów klas dziedziczących po klasach bazowych, bez dokładnej znajomości tych obiektów. [1]

Zasada została sformułowana po raz pierwszy przez Barbarę Liskov w książce Data Abstraction and Hierarchy[2], a spopularyzowana i podana w obecnym brzmieniu przez Roberta C. Martina w artykule "Principles of Object Oriented Design"[3] oraz książce "Agile Software Development: Principles, Patterns, and Practices"

Przykład naruszenia zasady[edytuj | edytuj kod]

Załóżmy, że dana jest hierarchia dziedziczenia jak na diagramie poniżej.

Lsp.png

Typowym przykładem naruszenia zasady LSP byłoby zastosowanie C++ Run-Time Type Information (RTTI) w celu rozpoznania typu obiektu, a następnie wywołanie funkcji, która wykonuje operację na danym obiekcie:

void przetwarzajFigurę(Figura iFigura)
{
  if(typeid(iFigura) == typeid(Prostokąt))
    przetwarzajProstokąt(static_cast<Prostokąt>(iFigura));
 
  else if(typeid(iFigura) == typeid(Okrąg))
    przetwarzajOkrąg(static_cast<Okrąg>(iFigura));
 
  else if(typeid(iFigura) == typeid(Kwadrat))
    przetwarzajKwadrat(static_cast<Kwadrat>(iFigura));
}

Funkcja przetwarzajFigurę() wprowadza dodatkowe zależności w kodzie, ponieważ musi ona znać wszystkie klasy dziedziczące po klasie Figura. Oznacza to, że każde utworzenie nowej klasy dziedziczącej po klasie Figura, będzie prawdopodobnie wiązało się ze zmianą tej funkcji.

Jeśli spojrzymy na klasy Prostokąt oraz Kwadrat, można zauważyć, że klasa Kwadrat dziedziczy po klasie Prostokąt metody do ustawiania/pobierania wysokości oraz szerokości. W przypadku klasy Prostokąt obecność tych metod jest naturalna (każdy prostokąt może mieć wysokość różną od szerokości). Nie jest tak w przypadku klasy kwadrat, ponieważ zmiana jego szerokości wiąże się ze zmianą wysokości. Oznacza to, że wywołanie metody ustawSzerokość na klasie Kwadrat spowodowałoby zmianę wartości zwracanej przez metodę pobierzWysokosc. W takim przypadku, oprogramowanie musiałoby sprawdzać typ obiektu który zmienia, żeby wiedzieć w jaki sposób obiekt będzie się zachowywał po wprowadzeniu zmian. Taki styl programowania wprowadza dodatkowe zależności w kodzie i utrudnia jego późniejsze utrzymanie i rozwijanie.

Zobacz też[edytuj | edytuj kod]

Przypisy

  1. Robert C. Martin: The Liskov Substitution Principle (ang.). [dostęp 2010-02-20].
  2. Barbara Liskov: Data Abstraction and Hierarchy. SIGPLAN Notices, 1988.
  3. Robert C. Martin: The Principles of Object Oriented Design (ang.). [dostęp 2010-02-20].

Linki zewnętrzne[edytuj | edytuj kod]