LSP: 리스코프 치환 원칙
- 1988년 바바라 리스코프(Barbara Liskov)는 하위 타입(subtype)을 아래와 같이 정의
- 필요한 것은 치환(substitution) 원칙
- S 타입의 객체 o1, T 타입 객체 o2
- T 타입을 이용해서 정의한 프로그램 P에서 o2에 o1을 치환하더라도 P의 행위가 변하지 않는다면, S는 T의 하위 타입
상속을 사용하도록 가이드하기
License
는PersonalLicense
와BusinessLicense
라는 하위 타입이 존재- 이 설계는 LSP를 준수
Billing
애플리테이션의 행위가License
하위 타입 중 무엇을 사용하는지에 전혀 의존하지 않기 때문에
정사각형/직사각형 문제
- LSP를 위반하는 전형적인 문제로는 정사각형/직사각형 문제가 있음
Square
는Rectangle
의 하위 타입으로 적합하지 않음Rectangle
은 높이와 너비가 독립적으로 변경될 수 있지만Square
는 함께 변경됨
LSP와 아키텍처
- 객체 지향의 초창기에는 위 처럼 상속을 사용해서 가이드함
- 시간이 지나면서 인퍼에이스와 구현체에도 적용되는 광범위한 소프트웨어 설계 원칙으로 변모함
LSP 위배 사례
- 다양한 택시 파견 서비스를 통합하는 애플리케이션을 만들고 있다고 가정
- 고객은 어느 택시업체인지 신경쓰지 않고 가장 적합한 택시를 찾음
- 택시 파견 REST의 URI가 운전기사 데이터베이스에 저장되어있다고 가정
- 시스템이 고객에게 알맞은 기사를 선택하면, 해당 기사의 레코드의 URI를 호출해 고객 위치로 파견
- 레코드에는
taxi.com/driver/Bob
으로 존재 - 이를
purpecab.com/driver/Bob/pickupAddress/{address}/pickupTime/{time}/destination/{destination}
과 같이 구성해서 호출 - 즉 모든 택시 업체들은 위와 같은 포맷을 준수해야함
- 이때 새로운 업체(가장 큰 택시업체)가 들어왔는데 위 포맷을 준수하지않음
/destnation
을/dest
로 사용
- 조건문으로 업체를 보고 해당업체만 별도로 처리?
- 회사도메인 하드코딩필요
- 이해할 수 없는 온갖 종류의 에러 발생 여지를 만듬
- 실력 있는 아키텍트는 이런식으로 구성하지 않음
- 레코드에는
- 아키텍트는 버그로 부터 시스템을 격리해야함
- URI를 키로 사용하는 설정용 데이터베이스 구성
URL | Dispatch Format |
---|---|
new-taxi.com | /pickupAddress/%s/pickupTime/%s/dest/%s |
* | /pickupAddress/%s/pickupTime/%s/destination/%s |
- 그 외 위 관련 로직에 복잡한 매커니즘을 추가 해야할 수 있음
결론
- LSP는 아키텍처 수준까지 확장 가능, 반드시 확장해야함
- 치환 가능성을 조금이라도 위배하면 시스템 아키텍처가 오염
- 별도의 메커니즘을 추가해야 할 수 있음