SOLID принциптеринде 'L' тамгасы эмне үчүн жооптуу?
sobes.tech AI
AIден жооп
Лисковтун алмаштыруу принциби (Liskov алмаштыруу принциби).
Бул принципке ылайык, программадагы объекттер алардын подкласстарынын үлгүлөрү менен алмаштырылышы керек, программа туура иштебей калбашы үчүн.
Башкача айтканда, эгер B классы A классынын подклассы болсо, анда программада A типтеги ар кандай объект B типтеги объект менен алмаштырылса, программа туура иштөөүн улантат.
Бул принцип ийкемдүү жана өзгөртүүгө туруктуу архитектура түзүүгө жардам берет, мурас алуу учурунда пайда болгон терс таасирлерди минималдаштырып.
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 { // Квадрат — туурасүздүн подклассы
override var width: Double {
didSet {
height = width // Кеңдик өзгөргөндө, бийиктик да өзгөрөт
}
}
override var height: Double {
didSet {
width = height // Бийиктик өзгөргөндө, кеңдик да өзгөрөт
}
}
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)
// Бул 5x5 өлчөмүндөгү квадрат деп эсептейбиз, аянты 25.
// Бирок, аны `Rectangle` күтүп жаткан функцияда колдонгондо,
// анын жүрүм-туруму күтүлбөгөндөй болушу мүмкүн, эгер шириндикти же бийиктикти өзгөртсөңүз
// `calculateArea` чакырылышына чейин, анткени `Square` эки тарапты бирдей өзгөртөт.
// Мисал катары, эгер өзгөртпөсөңүз, натыйжа 25 болот, бирок, мисалы, `mySquare.width = 10` кылсаңыз,
// анын аянты 100 болот, бул `Rectangle` менен иштеген код үчүн күтүлбөгөн болушу мүмкүн.
print(calculateArea(of: mySquare)) // 25
Мисалда, Square LSP-ны бузуп жатат, анткени бир өлчөмдү өзгөртүү (width же height) башкасын да өзгөртөт.
LSP сактоо үчүн:
Бул учурда, иерархияны бөлүп же Square үчүн мурас алууну алмаштырып, композицияны колдонуу керек. Мисалы, жалпы интерфейс же протокол киргизип, аны Rectangle жана 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
Азыр Square жана Rectangle жалпы Shape протоколун ишке ашырат, жана биз алардын объекттерин Shape күтүлгөн жерлерде колдонсо болот, күтүлгөн жүрүм-турумду бузбай.
Эскертүү:
Бул котормолор Liskov алмаштыруу принципин түшүндүрүү үчүн ар башка тилдерде берилген жана оригиналдык мазмундагы мазмунда алмаштырбайт жана алмаштырат деген маанини сактайт.