본문 바로가기

클린 아키텍처

3부 설계원칙-LSP

LSP란?

S타입의 객체 o1 T타입 객체 o2가 있고, T타입을 사용하는 프로그램 P에서 o2자리에 o1을 치환하더라도 P의 행위가 변하지 않는다면 S는 T의 하위 타입니다.

위 코드에서 P의 o2.print는 어떤 타입(클래스)에 의존해서 행위를 진행하지 않는다. 즉 LSP란 치환하더라도 어떠한 특정 타입에 의존하지 않고 기대 된 기능을 실행해야 한다는 의미이다.

 

LSP 사용가이드

사용가이드는 매우 간단하다. 위 구조처럼 인터페이스(인터페이스일 필요는 없다)를 사용하고 그를 상속 받는 하위 타입을 두고 사용하면 된다. 위 코드에서는 Billing 애플리케이션의 행위는 License라는 인터페이스에만 의존하지 하위타입 중 무엇을 사용하는지 의존하지 않기때문에 어떤 클래스든 치환이 가능하다.

LSP위반시 나타나는 냄새

  • instanceof문 사용(api에서 if문을 사용해서 url주소를 매핑하는 것도 포함된다.)
  • 다운캐스팅 사용

representative rule

대리인은 자신이 대리하는 것에 대하여 관계까지 대리하지 않는다.

 

아래 예제를 보며 설명하겠다.

 

LSP를 위반한 정사각형/직사각형 문제(예제)

위 Rectangle(사각형)을 사용받는 Square(정사각형)라는 클래스가 있다고 생각해보자. 사각형은 높이와 길이가 다를 수 있다. 하지만 정사각형은 높이와 길이가 같아야 한다.

그래서 아래와 같이 코드를 작성 하였다고 해보자.

 

위 코드에서 문제는 Square에 있다.Square는 setter에서 높이와 길이를 동시에 설정하고 있다. 이로 인해 기존에 Rectangle에 작성했던 테스트 케이스는 통과가 할 수 없게 되었다. 즉 Suare는 Rectangle로 치환이 불가능하게 되었다는 이야기다. 

아래코드는 위 테스트케이스를 Square를 통과시키도록 instanceof를 추가한 코드다.

위처럼 instanceof를 추가하여 테스트케이스를 통과시키면 이 테스트코드는 Square라는 특정 타입에 의존하게된다. 이로인해 LSP가 지켜지지 않게 된다.

 위 문제는 representative rule 위반 이라고 볼수 있다. 기하학에서 직사각형과 정사각형은 포함관계에 있다. 하지만 우리가 만들는 SW(대리인)에서는 기하학에서의 관계를 공유하지 않는다는 것이다. 즉 SW에서는 정사각형이 직사각형의 포함관계가 아닐 수 있으며 즉 상속관계가 아니라는 뜻이 된다.

 

'클린 아키텍처' 카테고리의 다른 글

3부 설계원칙-DIP  (0) 2023.01.16
3부 설계원칙-ISP  (0) 2023.01.16
3부 설계원칙-OCP  (0) 2023.01.10
3부 설계원칙-SRP  (0) 2023.01.02
2부 패러다임  (0) 2022.12.22