본문 바로가기

카테고리 없음

리스코프 치환 원칙 예시코드

리스코프 치환 원칙(Liskov Substitution Principle, LSP)은 객체 지향 프로그래밍에서 중요한 원칙 중 하나로, 이 원칙은 Barbara Liskov에 의해 제안되었습니다. LSP의 핵심 아이디어는 "하위 클래스의 인스턴스는 상위 클래스의 인스턴스로 대체될 수 있어야 한다(즉, 치환될 수 있어야 한다)"는 것입니다.

간단한 예를 통해 LSP를 살펴보겠습니다.

잘못된 예:

직사각형(Rectangle)과 정사각형(Square) 클래스를 생각해보세요. 많은 사람들이 정사각형은 직사각형의 특별한 경우로 생각할 수 있기 때문에, 정사각형을 직사각형의 하위 클래스로 구현하려고 할 수 있습니다.

class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    def set_width(self, width):
        self._width = width

    def set_height(self, height):
        self._height = height

    def area(self):
        return self._width * self._height

class Square(Rectangle):
    def __init__(self, side_length):
        super().__init__(side_length, side_length)

    def set_width(self, width):
        super().set_width(width)
        super().set_height(width)

    def set_height(self, height):
        super().set_width(height)
        super().set_height(height)

위의 예에서 SquareRectangle의 하위 클래스입니다. 하지만 문제가 발생합니다. 만약에 우리가 직사각형의 너비와 높이를 독립적으로 변경할 수 있다고 가정했을 때, 정사각형의 경우에는 높이와 너비가 항상 같아야 합니다. 따라서 Square 클래스에서 높이나 너비를 변경하면 다른 하나도 같이 변경되어야 합니다.

이렇게 구현하면 Rectangle의 인스턴스로 Square의 인스턴스를 대체할 때 예상하지 못한 문제가 발생할 수 있습니다. 이는 LSP를 위반하는 것입니다.

올바른 예:

직사각형과 정사각형은 별도의 클래스로 처리하되, 공통의 인터페이스나 상위 클래스를 갖게 하는 것이 더 적절합니다.

class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    # ... (앞서의 구현과 같음)

class Square(Shape):
    def __init__(self, side_length):
        self._side_length = side_length

    def area(self):
        return self._side_length * self._side_length

이렇게 구현하면 각각의 특성에 맞게 독립적인 동작을 수행할 수 있으며, LSP를 위반하지 않습니다.