За шта је одговорно слово 'L' у принципима SOLID?
sobes.tech АИ
Одговор од АИ
Princip Liskovove zamene (Liskov princip zamene).
Prema ovom principu, objekti u programu treba da budu zamenjivi instancama svojih podtipova bez promene ispravnosti programa.
Drugim rečima, ako klasa B je podtip klase A, onda bilo koji objekat tipa A u programu može biti zamenjen objektom tipa B, i program će i dalje raditi ispravno.
Ovaj princip pomaže u stvaranju fleksibilnije i otpornije arhitekture, minimizirajući sporedne efekte pri radu sa nasleđivanjem.
Prekoračenje LSP:
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 { // Kvadrat je podtip pravougaonika
override var width: Double {
didSet {
height = width // Promena širine takođe menja visinu
}
}
override var height: Double {
didSet {
width = height // Promena visine takođe menja širinu
}
}
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)
// Pretpostavljamo da je ovo pravougaonik 5x5 sa površinom 25.
// Ali pri korišćenju u funkciji koja očekuje Rectangle,
// njegovo ponašanje može biti neočekivano ako promenimo širinu ili visinu
// pre poziva calculateArea, jer Square menja obe strane istovremeno.
// U ovom primeru, ako ne menjamo svojstva nakon inicijalizacije,
// rezultat će biti 25, ali ako, na primer, postavimo mySquare.width = 10
// njegova površina će biti 100, što može biti neočekivano za kod koji radi sa Rectangle.
print(calculateArea(of: mySquare)) // 25
U primeru, Square krši LSP, jer promena jednog dimenzije (width ili height) takođe menja drugu. Ako koristimo objekat Square tamo gde se očekuje Rectangle, to može dovesti do neočekivanog ponašanja, jer kod koji radi sa Rectangle može pretpostaviti mogućnost nezavisne promene strana.
Poštovanje LSP:
Da bismo poštovali LSP u ovom slučaju, možemo podeliti hijerarhiju ili koristiti kompoziciju umesto nasleđivanja za Square. Na primer, uvesti zajednički interfejs ili protokol za figure koje imaju površinu, i implementirati ga u Rectangle i 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
Sada Square i Rectangle implementiraju zajednički protokol Shape, i možemo koristiti objekte oba tipa tamo gde se očekuje Shape, bez narušavanja očekivanog ponašanja.