리스코프 치환 원칙

치환성(영어: substitutability)은 객체 지향 프로그래밍 원칙이다. 컴퓨터 프로그램에서 자료형 S {\displaystyle S} 가 자료형 T {\displaystyle T} 의 서브타입라면 필요한 프로그램의 속성(정확성, 수행하는 업무 등)의 변경 없이 자료형 T {\displaystyle T} 의 객체를 자료형 S {\displaystyle S} 의 객체로 교체(치환)할 수 있어야 한다는 원칙이다. 리스코프 치환 원칙(영어: Liskov substitution principle, LSP)은 바바라 리스코프가 자료 추상화와 계층 (Data abstraction and hierarchy)이라는 제목으로 기조연설을 한 1987년 컨퍼런스에서 처음 소개한 내용으로, 이 원칙을 엄밀한 용어로 말하자면 (강한) 행동적 하위형화라 부르는 하위형화 관계의 특정한 사례이다. 이 정의는 1994년 논문에서 다음 원칙을 만들어낸 자료형의 의미론적 상호처리를 보장하기 때문에 단순한 문법적 관계일 뿐만 아니라 의미론적 관계다. q ( x ) {\displaystyle q(x)} 를 자료형 T {\displaystyle T} 의 객체 x {\displaystyle x} 에 대해 증명할 수 있는 속성이라 하자. 그렇다면 S {\displaystyle S} 가 T {\displaystyle T} 의 하위형이라면 q ( y ) {\displaystyle q(y)} 는 자료형 S {\displaystyle S} 의 객체 y {\displaystyle y} 에 대해 증명할 수 있어야 한다. 같은 논문에서 리스코프와 윙은 사전 및 사후 조건으로 하위형화의 상호 작용을 고려함으로써 행동 하위형화 개념을 베르트랑 메이어의 계약에 의한 설계와 분명한 유사성을 지닌 호어 논리의 확장으로 자세히 설명한다. 리스코프의 '행동적 하위형'이라는 개념은 '가변 객체의 치환성'이라는 개념을 정의한다. 즉 자료형 S {\displaystyle S} 가 자료형 T {\displaystyle T} 의 하위형이라면, 프로그램에서 자료형 T {\displaystyle T} 의 객체는 프로그램의 속성을 변경하지 않고 자료형 S {\displaystyle S} 의 객체로 교체할 수 있다. (예: 정확성) 행동의 하위형화는 형 이론에서 인수형의 반공변성과 반환형의 공변성에 의존하여 정의한 일반적 기능의 하위형화보다 더 강한 개념이다. 행동의 하위형은 일반적으로 명백하게 결정 불가능하다. " x {\displaystyle x} 에 대해 항상 종료할 수 있는 메서드"라는 속성을 q {\displaystyle q} 라고 할 때, 임의의 프로그램(예: 컴파일러)이, 속성 q {\displaystyle q} 가 자료형 T {\displaystyle T} 에 대해 참임을 유지한다 하더라도 자료형 T {\displaystyle T} 의 어떤 하위형 S {\displaystyle S} 에 대해 참을 유지한다는 것을 증명하기란 불가능하다. 그럼에도 불구하고 이 원칙은 클래스의 계층 구조를 설계할 때 유용하다. 리스코프의 원칙은 새로운 객체 지향 프로그래밍 언어에 채용된 시그니처에 관한 몇 가지 표준적인 요구사항을 강제한다. 하위형에서 메서드 인수의 반공변성 하위형에서 반환형의 공변성 하위형에서 메서드는 상위형 메서드에서 던져진 예외의 하위형을 제외하고 새로운 예외를 던지면 안된다. 여기에 더하여 하위형이 만족해야하는 행동 조건 몇 가지가 있다. 이것은 계약이 상속에 대해 어떻게 상호작용하는지에 대한 제약조건을 유도하는 계약에 의한 설계 방법론과 유사한 용어로 자세히 설명되어있다. 하위형에서 선행조건은 강화될 수 없다. 하위형에서 후행조건은 약화될 수 없다. 하위형에서 상위형의 불변조건은 반드시 유지되어야 한다. 이력 제약 조건 (이력 규칙). 객체는 그 자신의 메서드를 통해서만 수정(캡슐화)할 수 있는 것으로 간주된다. 하위형은 상위형에 없는 메서드를 추가할 수 있기 때문에, 추가된 메서드를 통해 상위형에서 허용하지 않는 하위형 상태의 변경을 일으킬 수 있다. 리스코프와 윙이 도입한 참신한 요소인 이력 제약조건은 이를 방지한다. 이 제약조건의 위반을 정의하기 위해 변경 가능 지점을 변경 불가 지점의 하위형으로 정의해 볼 수 있다. 변경 불가 지점의 이력은 생성한 이후 상태가 항상 동일해야 하기 때문에, 앞에서 가정한 정의는 이력 제약조건의 위반이며, 따라서 일반적으로 변경 가능 위치를 이력에 포함할 수 없다. 반면 하위형에 추가된 필드는 상위형의 메서드로 감시할 대상이 아니기 때문에 안정적으로 수정할 수 있다. 따라서 고정된 점에서 고정된 중심점과 변경 가능한 반지름을 가진 원을 LSP를 위반하지 않고 유도할 수 있다. 사전 및 사후 조건에 관한 규칙은 베르트랑 메이어가 1988년의 저서에서 도입한 개념과 동일하다. 메이어와 이후에 '행동의 하위형'이라는 용어를 처음 사용한 피에르 아메리카 모두 임의의 행동의 하위형 개념에 대한 증명 이론적 정의를 제공했으나, 참조나 포인터를 지원하는 프로그래밍 언어에서 일어날 수 있는 별칭에 대한 고려는 없었다. 1994년 리스코프와 윙이 만든 중요한 개선점은 별칭에 대한 고려였고 핵심 요소는 이력 제약 조건이다. 메이어와 아메라카의 정의에서는 LSP에서 허용하지 않는 변경 가능 지점은 변경 불가 지점의 행동의 하위형이어야 했다. LSP를 위반하는 전형적인 예로, 너비와 높이의 조회(getter) 및 할당(setter) 메서드를 가진 직사각형 클래스로부터 정사각형 클래스를 파생하는 경우를 들 수 있다. 정사각형 클래스는 항상 너비와 높이가 같다고 간주할 수 있다. 정사각형 객체가 직사각형을 다루는 문맥에서 사용되는 경우, 정사각형의 크기는 독립적으로 변경할 수 없기 때문에 (혹은 그래서는 안되기 때문에) 예기치 못한 행동을 하게 된다. 이 문제는 고치기 쉽지 않다. 정사각형 클래스의 할당 메서드를 수정하여 정사각형의 불변 조건(즉, 너비와 높이가 같음)을 유지하면, 이 메서드는 크기를 독립적으로 변경할 수 있다고 설명한 직사각형의 할당자의 사후 조건을 무력화(위반)한다. 이러한 LSP 위반은 실전에서는 LSP를 위반한 클래스를 사용하는 코드가 실제로 기대하는 사후 조건이나 불변 조건에 따라 문제가 될 수도 있고 아닐수도 있다. 여기서 중요한 사안은 가변성이다. 정사각형과 직사각형이 조회 메서드만 가진다면 (즉, 이들이 불변 객체라면), LSP 위반을 발생하지 않는다. Refinement SOLID - "SOLID"의 "L"는 리스코프 치환 원칙에 해당한다. Type signature Composition over inheritance 일반 참고 문헌 Gary T. Leavens and Krishna K. Dhara, Concepts of Behavioral Subtyping and a Sketch of Their Extension to Component-Bases Systems in Gary T. Leavens, Murali Sitaraman, (ed.) Foundations of component-based systems, Cambridge University Press, 2000 ISBN 0-521-77164-1. This paper surveys various notions of behavioral subtyping, including Liskov and Wing's. Liskov, B. H.; Wing, J. M. (1994년 11월). 《A behavioral notion of subtyping》. 《ACM Trans. Program. Lang. Syst.》 16 (6). 1811–1841쪽. doi:10.1145/197320.197383.  An updated version appeared as CMU technical report: Liskov, Barbara; Wing, Jeannette (July 1999). “Behavioral Subtyping Using Invariants and Constraints” (PS). 2006년 10월 5일에 확인함.  더 이상 지원되지 않는 변수를 사용함 (도움말) The formalization of the principle by its authors. Reinhold Plösch, Contracts, scenarios and prototypes: an integrated approach to high quality software, Springer, 2004, ISBN 3-540-43486-0. Contains a gentler introduction to behavioral subtyping in its various forms in chapter 2. Robert C. Martin, The Liskov Substitution Principle, C++ Report, March 1996. An article popular in the object-oriented programming community that gives several examples of LSP violations. Kazimir Majorinc, Ellipse-Circle Dilemma and Inverse Inheritance, ITI 98, Proceedings of the 20th International Conference of Information Technology Interfaces, Pula, 1998, ISSN 1330-1012. This paper discusses LSP in the mentioned context. 특정 참고 문헌 Liskov, B. (1988년 5월). “Keynote address - data abstraction and hierarchy”. 《ACM SIGPLAN Notices》 23 (5): 17–34. doi:10.1145/62139.62141.  A keynote address in which Liskov first formulated the principle. Meyer B., Object-oriented Software Construction, Prentice Hall, New York, 1988, ISBN 0-13-629031-0 자료형 수준보다는 클래스 수준에서; 이 둘의 구별을 위해서는 nominal vs. structural subtyping을 참고하라. The Liskov Substitution Principle, T. S. Norvell, 2003