yoongrammer

리스코프 치환 원칙 (LSP: Liskov Substitution Principle) 본문

OOP

리스코프 치환 원칙 (LSP: Liskov Substitution Principle)

yoongrammer 2022. 4. 30. 23:59
728x90

목차

    리스코프 치환 원칙 (LSP: Liskov Substitution Principle)


     

    S가 T의 하위 유형이면 프로그램에서 자료형 T의 객체는 해당 프로그램의 원하는 속성을 변경하지 않고 자료형 S의 객체로 교체(치환)할 수 있어야 한다.

    바바라 리스코프(Babara Liskov)

     

    로버트 C마틴은 이것을 다음과 같이 요약했습니다.

    자식 클래스는 부모 클래스를 대체할 수 있어야 한다.

     

    이 원칙의 핵심은 부모 클래스를 사용하는 위치에 자식 클래스를 대신 사용했을 때 코드가 원래 의도대로 작동해야 한다는 것을 의미합니다.

     

    LSP 위반 사례


    일반적으로 많이 드는 예시가 바로 직사각형을 상속한 정사각형 클래스의 예시입니다.

    class Rectangle:
    	def __init__(self, width, height):
    		self.width = width
    		self.height = height
    	
    	def get_area(self):
    		return self.width * self.height
    
    	def set_width(self, value):
    		self.width = value
    	
    	def set_height(self, value):
    		self.height = value
    
    class Square(Rectangle):
    	def __init__(self, side):
    		self.width = side
    		self.height = side
    	
    	def set_width(self, value):
    		self.width = value
    		self.height = value
    
    	def set_height(self, value):
    		self.width = value
    		self.height = value

    정사각형은 직사각형의 한 종류이기 때문에 정사각형은 직사각형을 상속받을 수 있습니다.

    그러나 Rectangle 객체를 Square 객체로 바꾸면 어떤 일이 발생하는지 살펴보겠습니다.

    r = Rectangle(4,5)
    r.set_width(5)
    r.set_height(6)
    print(r.get_area())
    
    r1 = Square(4)
    r1.set_width(5)
    r1.set_height(6)
    print(r1.get_area())

    위 코드에서 Rectangle 객체를 Squear로 대체한 것을 볼 수 있고 이 코드의 결과는 아래와 같습니다.

    30
    36

    정사각형의 특징때문에 길이와 너비를 동일한 값으로 설정하려고 Rectangle클래스의 set_width, set_height를 변경했기 때문에 결과가 다르게 나왔습니다. 이는 LSP를 위반합니다.

     

    정사각형은 직사각형일 수 있지만 Squer 객체는 Rectangle 객체가 아닙니다. 이는 Square 객체의 동작이 Rectangle 객체의 동작과 일치하지 않기 때문입니다. 

    결론


    LSP는 자식클래스가 오류를 일으키지 않고 부모 클래스를 대신할 수 있도록 하는 것을 목표로 합니다.

     

    LSP를 지키면 OCP(Open Closed Principle)를 확장하고 응용 프로그램을 중단하지 않고 상위 클래스의 객체를 하위 클래스의 객체로 바꿀 수 있습니다. 이를 위해서는 모든 하위클래스가 상위 클래스와 동일한 방식으로 동작해야 합니다.

     

     

    728x90
    Comments