Sobes.tech
Junior

Par ko atbild burts 'L' SOLID principos?

sobes.tech AI

Atbilde no AI

Liskova aizvietošanas princips (Liskov Substitution Principle).

Saskaņā ar šo principu, programmā objektiem jābūt aizvietojamiem ar to apakštipiem, nemainot programmas pareizību.

Citiem vārdiem, ja klase B ir klases A apakšklase, tad jebkurš A tipa objekts programmā var tikt aizvietots ar B tipu, un programma turpinās darboties pareizi.

Šis princips palīdz veidot elastīgāku un izturīgāku arhitektūru, samazinot blakusparādības mantošanas gadījumā.

LSP pārkāpums:

class Rectangle {
    var width: Double
    var height: Double

    init(width: Double, height: Double) {
        self.width = width
        self.height = height
    }

    var area: Double {
        return width * height
    }
}

class Square: Rectangle { // Kvadrāts ir taisnstūra apakšklase
    override var width: Double {
        didSet {
            height = width // Svars maiņa arī maina augstumu
        }
    }

    override var height: Double {
        didSet {
            width = height // Augstuma maiņa arī maina platumu
        }
    }

    init(side: Double) {
        super.init(width: side, height: side)
    }
}

func calculateArea(of rectangle: Rectangle) -> Double {
    return rectangle.area
}

let myRectangle = Rectangle(width: 5, height: 10)
print(calculateArea(of: myRectangle)) // 50

let mySquare = Square(side: 5)
// Pieņemsim, tas ir 5x5 taisnstūris ar platību 25.
// Bet, izmantojot funkcijā, kas sagaida `Rectangle`,
// tā uzvedība var būt neparedzama, ja maina platumu vai augstumu
// pirms `calculateArea` izsaukšanas, jo `Square` maina abas puses vienlaicīgi.
// Šajā piemērā, ja neizmaina īpašības pēc inicializācijas,
// rezultāts būs 25, bet, ja, piemēram, iestatīsim mySquare.width = 10
// pirms `calculateArea` izsaukšanas, tā platība kļūs par 100, kas var būt
// negaidīti `Rectangle` kodam.
print(calculateArea(of: mySquare)) // 25

Šajā piemērā Square pārkāpj LSP, jo viena dimensija (width vai height) maiņa arī maina otru. Ja izmantojam Square objektu tur, kur sagaidīts Rectangle, tas var novest pie negaidītas uzvedības, jo Rectangle kods var pieņemt, ka puses var mainīties neatkarīgi.

LSP ievērošana:

Lai ievērotu LSP šajā gadījumā, var sadalīt hierarhiju vai izmantot kompozīciju vietā mantošanu Square. Piemēram, ieviest kopēju saskarni vai protokolu figūrām, kurām ir platība, un realizēt to Rectangle un Square.

protocol Shape {
    var area: Double { get }
}

class Rectangle: Shape {
    var width: Double
    var height: Double

    init(width: Double, height: Double) {
        self.width = width
        self.height = height
    }

    var area: Double {
        return width * height
    }
}

class Square: Shape {
    var side: Double

    init(side: Double) {
        self.side = side
    }

    var area: Double {
        return side * side
    }
}

func calculateShapeArea(of shape: Shape) -> Double {
    return shape.area
}

let myShapeRectangle: Shape = Rectangle(width: 5, height: 10)
print(calculateShapeArea(of: myShapeRectangle)) // 50

let myShapeSquare: Shape = Square(side: 5)
print(calculateShapeArea(of: myShapeSquare)) // 25

Tagad Square un Rectangle realizē kopēju protokolu Shape, un mēs varam izmantot abu klases objektus tur, kur sagaidīts Shape, ne pārkāpjot sagaidāmo uzvedību.