Sobes.tech
Senior

Któja z zasad SOLID jest dla ciebie najtrudniejsza do zastosowania w praktyce?

sobes.tech AI

Odpowiedź od AI

Zasada podstawienia Barbary Liskov (LSP).

Trudność polega na tym, że naruszenie LSP nie zawsze jest oczywiste na pierwszy rzut oka i może ujawnić się dopiero przy użyciu podklas w kontekście, w którym oczekiwane jest zachowanie klasy bazowej. Wymaga to głębokiego zrozumienia przewidywanego zachowania klasy bazowej i dokładnych testów.

Przykład naruszenia:

class Rectangle {
    var width: Double = 0
    var height: Double = 0

    func setWidth(_ width: Double) { self.width = width }
    func setHeight(_ height: Double) { self.height = height }

    func area() -> Double { width * height }
}

class Square: Rectangle {
    override func setWidth(_ width: Double) {
        super.setWidth(width)
        super.setHeight(width) // Naruszenie LSP: zmiana szerokości wpływa na wysokość
    }

    override func setHeight(_ height: Double) {
        super.setHeight(height)
        super.setWidth(height) // Naruszenie LSP: zmiana wysokości wpływa na szerokość
    }
}

Jeśli używać Square tam, gdzie oczekiwany jest Rectangle, zachowanie Square przy zmianie tylko jednej strony (szerokości lub wysokości) doprowadzi do nieprzewidywalnych rezultatów, ponieważ klasa bazowa Rectangle nie ma takiego zachowania.

Aby zapobiec naruszeniom LSP, często konieczne jest przemyślenie hierarchii klas, użycie kompozycji zamiast dziedziczenia lub wprowadzenie bardziej abstrakcyjnych interfejsów/protokołów. Może to zwiększyć złożoność projektowania na wczesnych etapach.

Tabela porównawcza:

Zasada SOLID Krótki opis Główna trudność w stosowaniu LSP
S (SRP) Jedna klasa - jeden powód do zmiany Znalezienie "jednego powodu"
O (OCP) Otwarte na rozszerzenia, zamknięte na modyfikacje Prawidłowe użycie abstrakcji
L (LSP) Podklasy powinny być wymienialne za klasy bazowe Nieoczywiste naruszenia, wymaga zrozumienia kontraktu klasy bazowej
I (ISP) Klienci nie powinni zależeć od nieużywanych metod Podział interfejsów
D (DIP) Zależność od abstrakcji, a nie od konkretnych implementacji Wstrzykiwanie zależności