Ի՞նչ է պատասխանատու 'L' տառը SOLID սկզբունքներում։
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-ի համար:
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-ի փոխարինման սկզբունքը տարբեր լեզուներով, և չեն փոխարինում կամ փոխարինում են բնօրինակի բովանդակությանը։