-
[SOLID] 리스크프 치환 원칙 (Liskov Subsitution Principle)Programming/CS 2021. 12. 19. 20:13
리스코프 치환 원칙 (Liskov Substituion Principle)
만약 S가 T의 서브 타입이면, T는 S의 타입으로 대체될 수 있다는 원칙이다
예를들어 고양이(Cat)가 있으며,
그 고양이의 서브타입인 검은 고양이(Black Cat)와 하얀 고양이(White Cat)가 있다고 하자.
그럼 고양이(Cat)는 검은 고양이가 될 수도 있으며 하얀 고양이가 될 수 있다는 원리이다.
검은 고양이랑 하얀 고양이가 가지고 있는 공통된 속성들은 모두 고양이에게서 파생되었기 때문에이들의 프로토타입인 고양이(Cat)는 이의 파생된 모든 요소에 대해서 대체가 가능하게 된다.
코드로 예를 들어보면,
그냥 고양이를 정의한 클래스가 있고 그 클래스에는 고양이가 말을 하는 기능인 speak 함수가 들어가 있다.
그리고 그 하위로 검은 고양이와 하얀 고양이의 클래스를 정의했고 고양이의 기능인 speak함수를 해당 고양이의 속성에 맞게 재정의 했다.
class Cat { public: virtual void speak() const { std::cout << "그냥 고양이 냥냥" << "\n"; } }; class BlackCat : public Cat { public: virtual void speak() const override { std::cout << "검은 고양이 냥냥냥" << "\n"; } }; class WhiteCat : public Cat { public: virtual void speak() const override { std::cout << "하얀고양이 냥냥냥" << "\n"; } };
그리고 각 고양이의 speak 함수를 실행시킬 수 있는 speak 함수를 전역으로 만들었다.
void speak(const Cat& cat) { cat.speak(); }
각 고양이 객체를 생성해주고 해당 객체의 공통된 함수인 speak함수를 실행기켜주는 전역 스코프에 위치한 speak 함수에 각 객체를 넣어줬다.
검은 고양이와 햐얀 고양이 객체의 부모인 Cat 객체는 그대로 Cat 클래스에 정의된 speak가 실행이 된다.
검은 고양이(BlackCat)와 하얀 고양이 클래스는 부모 객체인 Cat클래스로 변환이 되면서 리스코프 치환 원칙에 의해서 재정의된 speak함수가 호출이 될 것이다.
int main(void) { Cat cat = Cat(); speak(cat); BlackCat blackCat = BlackCat(); speak(blackCat); // 검은 고양이(BlackCat) -> 고양이(Cat)으로 대체 WhiteCat whiteCat = WhiteCat(); speak(whiteCat); // 하얀 고양이(WhiteCat) -> 고양이(Cat)으로 대체 return 0; }
이제 여기에 새로운 클래스인 냥캣(NyanCat) 클래스를 만들어보자
냥캣의 경우 따로 말을 하지 않기 때문에 있어서는 안된다.
따라서 이의 경우 리스코프 치환 원칙에 위배되는 사항이 된다.
#include <stdexcept> class NyanCat : public Cat { public: virtual void speak() const override { throw std::runtime_error("Nyan Cat cannot speak"); } };
이를 방지하기 위해서는 처음 설계 차원에서 문제가 일어나지 않도록 설계를 해야된다고 한다.
'Programming > CS' 카테고리의 다른 글
[SOLID] 개방 폐쇠 원칙 (Open Closed Principle) (0) 2021.12.16 [SOLID] 단일 책임 원칙 (Single Responsibility Principle) (0) 2021.12.14