Milline SOLID põhimõtetest on teile kõige raskem praktikas rakendada?
sobes.tech AI
Vastus AI-lt
Barbara Liskov's substitution principle (LSP).
The complexity lies in the fact that violating LSP is not always obvious at first glance and may only be revealed when subclasses are used in a context where the behavior of the base class is expected. This requires a deep understanding of the expected behavior of the base class and thorough testing.
Example of violation:
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) // LSP violation: changing width affects height
}
override func setHeight(_ height: Double) {
super.setHeight(height)
super.setWidth(height) // LSP violation: changing height affects width
}
}
Using Square where Rectangle is expected, the behavior of Square when changing only one side (width or height) will lead to unpredictable results, as the base class Rectangle does not have such behavior.
To prevent LSP violations, it is often necessary to rethink class hierarchies, use composition instead of inheritance, or introduce more abstract interfaces/protocols. This can add complexity to the design at early stages.
Comparison table:
| SOLID Principle | Brief Description | Main difficulty in applying LSP |
|---|---|---|
| S (SRP) | One class - one reason for change | Finding "the single reason" |
| O (OCP) | Open for extension, closed for modification | Proper use of abstractions |
| L (LSP) | Subclasses should be replaceable by base classes | Obscurity of violations, requires understanding of the contract |
| I (ISP) | Clients should not depend on unused methods | Interface segregation |
| D (DIP) | Dependence on abstractions, not on concrete implementations | Dependency injection |