83 lines
1.5 KiB
Ruby
83 lines
1.5 KiB
Ruby
# Liskov’s principle tends to be the most difficult to understand. The principle
|
||
# states that you should be able to replace any instances of a parent class
|
||
# with an instance of one of its children without creating any unexpected or
|
||
# incorrect behaviors.
|
||
|
||
class Rectangle
|
||
def initialize(height, width)
|
||
@height = height
|
||
@width = width
|
||
end
|
||
|
||
def set_height(height)
|
||
@height = height
|
||
end
|
||
|
||
def set_width(width)
|
||
@width = width
|
||
end
|
||
|
||
def square
|
||
@width * @height
|
||
end
|
||
end
|
||
|
||
# Solution
|
||
|
||
# LSP says is if we know the interface of Rectangle, We need to be able to guess
|
||
# the interface of subtype class Square
|
||
# Square.new(3).square => 9
|
||
|
||
class Square < Rectangle
|
||
def initialize(side)
|
||
super(side, side)
|
||
end
|
||
|
||
def set_height(height)
|
||
super(height)
|
||
@width = height
|
||
end
|
||
|
||
def set_width(width)
|
||
super(width)
|
||
@height = width
|
||
end
|
||
end
|
||
|
||
# Another common instance of a Liskov violation is raising an exception for an
|
||
# overridden method in a child class. It’s also not uncommon to see methods
|
||
# overridden with modified method signatures causing branching on type in
|
||
# classes that depend on objects of the parent’s type. All of these either
|
||
# lead to unstable code or unnecessary and ugly branching.
|
||
|
||
class Animal
|
||
def walk
|
||
'walking_as_animal'
|
||
end
|
||
end
|
||
|
||
class Cat < Animal
|
||
def run
|
||
'run_as_cat'
|
||
end
|
||
end
|
||
|
||
# Solution
|
||
|
||
class Animal
|
||
def walk
|
||
'walking_as_animal'
|
||
end
|
||
|
||
def run
|
||
raise NotImplementedError
|
||
end
|
||
end
|
||
|
||
class Cat < Animal
|
||
def run
|
||
'run_as_cat'
|
||
end
|
||
end
|
||
|