[객체지향] SOLID(3) - LSP(리스코프 치환 원칙)
LSP(Liskov Substitution Principle)
리스코프 치환 원칙이란 자식 클래스는 자신의 부모 클래스를 대체할 수 있다는 것을 말한다. 리스코프 치환 원칙은 바바라 리스코프가 '자료 추상화와 계층'이라는 제목으로 기초 연설을 한 1987년 콘퍼런스에서 처음 소개한 내용으로, 이 원칙을 엄밀한 용어로 말하자면 (강한) 행동적 하위형화라고 부르는 하위형화 관계의 특정한 사례이다. 이 정의는 1994년 논문에서 다음 원칙을 만들어낸 자료형의 의미론적 상호 처리를 보장하기 때문에 단순한 문법적 관계일 뿐만 아니라 의미론적 관계다.
q(x)를 자료형 T의 객체 x에 대해 증명할 수 있는 속성이라 하자. 그렇다면 S가 T의 하위형이라면 q(y)는 자료형 S의 객체 y에 대해 증명할 수 있어야 한다.
리스코프의 '행동적 하위형'이라는 개념은 가변 객체의 치환성이라는 개념을 정의한다. 행동의 하위형화는 형 이론에서 인수형의 반공변성과 반환형의 공변성에 의존하여 정의한 일반적 기능의 하위형화보다 더 강한 개념이다. 리스코프의 원칙은 새로운 객체 지향 프로그래밍 언어에 사용된 시그니처에 관한 몇 가지 표준적인 요구사항을 강제한다.
- 하위형에서 메서드 인수의 반공변성
- 하위형에서 반환형의 공변성
- 하위형에서 메서드는 상위형 메서드에서 던져진 예외의 하위형을 제외하고 새로운 예외를 던지면 안 된다.
여기에 더하여 하위형이 만족해야 하는 행동 조건 몇 가지가 있다. 이것은 계약이 상속에 대해 어떻게 상호작용 하는지에 대한 제약 조건을 유도하는 계약에 의한 설계 방법론과 유사한 용어로 자세히 설명되어 있다.
- 하위형에서 선행 조건은 강화될 수 없다.
- 하위형에서 후행 조건은 약화될 수 없다.
- 하위형에서 상위형의 불변 조건은 반드시 유지되어야 한다.
LSP를 위반하는 전형적인 예로, 너비와 높이의 조회 및 할당 메서드를 가진 직사각형 클래스로부터 정사각형 클래스를 파생하는 경우를 들 수 있다. 정사각형 클래스는 항상 너비와 높이가 같다고 간주할 수 있다. 정사각형 객체가 직사각형을 다루는 문맥에서 사용되는 경우, 정사각형의 크기는 독립적으로 변경할 수 없기 때문에 예기치 못한 행동을 하게 만든다. 정사각형 클래스의 할당 메서드를 수정하여 정사각형의 불변 조건(너비=높이)을 유지하면, 이 메서드는 크기를 독립적으로 변경할 수 있다고 설명한 직사각형의 할당자의 사후 조건을 위반한다. 이러한 LSP 위반은 실전에서는 LSP를 위반한 클래스를 사용하는 코드가 실제로 기대하는 사후 조건이나 불변 조건에 따라 문제가 될 수도 있고, 아닐 수도 있다. 여기서 중요한 사안은 가변성이다. 정사각형과 직사각형이 조회 메서드만 가진다면(불변 객체라면), LSP를 위반하지 않는다.