도니의 iOS 프로그래밍 세상

[오브젝트] 13장 - 서브 클래싱 및 서브 타이핑(2) 본문

OOP

[오브젝트] 13장 - 서브 클래싱 및 서브 타이핑(2)

Donee 2024. 7. 21. 00:08

LSP

  • 서브 타입과 서브 클래스가 부모 클래스, 상위 타입 대체가 가능 해야함
  • 불가능한 예시
    • 직사각형, 정사각형
    • 현실에서는 정사각형은 직사각형의 한 종류 지만, 동작이 달라 상속이 불가능 함
    • why? 정사각형은 높이를 변경하면, 너비도 함께 바뀜(
    • 따라서, 두 사각형의 높이를 변경했을 때 넓이의 변화가 다름(직사각형은 높이만큼, 정사각형은 변경된 높이의 제곱만큼 영향을 받음)
  • 따라서 클라이언트의 가정에 따라 부모 클래스 가정을 세우고 맞게 처리해야 함
  • is-a 관계는 클라의 입장에서 고려, 자식 객체가 부모 객체의 행동을 대체할 수 있어야 함(속성은 필요X)

LSP의 효과

  • 유연한 설계(어떤 자식 클래스과도 안정적으로 협력이 가능)
  • OCP를 위한 전제 조건
    • why? 위반시엔 자식 클래스를 추가할 때마다 문제가 발생하기 때문

계약에 의한 설계

  • 서브 타입은, LSP 만족을 위해 클라이언트 ↔ 슈퍼타입 간 체결된 계약을 준수
  • 계약에는 사전조건, 사후조건, 클래스 불변식
  • 사전 조건은 클라이언트가 정상적 메서드 실행하기 위해 만족시켜야 함
  • 사후 조건은 메서드 실행 후, 서버가 클라에게 보장해야 함
  • 두 조건을 만족하지 못하면, 협력에 문제가 발생

사전 조건 위반 예시

  • 서브 타입은 더 강력한 사전 조건을 정의할 수 없음
  • 만약 정의하게 된다면 다음과 같은 문제점 발생
class Example {
   
   private var calculator: Calculator

   private let number: Int

   func calculate() -> Int? { 
      if number >= 0 {
         return calculator.execute(value: number)
      }
      
      return nil
   } 
 
}
  • Example 객체는, Calculator 객체와 협력
  • Calculator 객체는 전달받은 number를 특별한 규칙에 의해 계산 후, 값을 전달(이때, 음수를 전달받으면 음수를 에러가 발생함)
  • Example은 양수외에는 nil을 리턴하는 구조
  • 이때, Calculator 의 사전 조건은 양수만을 전달할 것임
class ScientificCalculator: Calculator {
   
    func execute(value: Int) -> Int {
        assert(value >= 10, "Value must be 10 or greater")
    }
}
  • ScientificCalculator 라는 Calculator 의 파생 클래스
  • 해당 객체는, 양수중에서도 10이상의 숫자만 들어와야 함
  • 하지만, 협력객체인 Example 은 이걸 알수 없어, 에러가 계속 발생
  • 결국 서브 타입 의 사전 조건이 부모 타입보다 더 컸을 때 위험

사후 조건 위반 사례

  • 서브타입은 슈퍼타입과 같거나 더 강한 사후조건 정의 가능
  • 더 약한 사후조건은 정의할 수 없음
  • 위 Example객체는 Calculator 가 항상 양수 이상의 값을 전달한다고 생각
class OfficeCalculator: Calcuator {
   
   func execute(value: Int) -> Int {
      return value * -1
   }
}
  • 위와같이, OfficeCalcualtor 에서 음수를 전달한다면, 협력 객체인 Example 에서는 에러가 발생
  • 위 사례는, 서브타입이 슈퍼타입 보다 더 약한 사후조건을 정의하여 문제가 발생

결론

  1. LSP 즉 서브 타입이 슈퍼 타입을 대체할 수 있어야 함
  2. 서브 타입은 객체 협력간 사전 조건, 사후 조건을 만족시켜야 함
  3. 서브 타이핑을 원한다면, 슈퍼 타입의 계약관계 및 클라이언트의 가정을 잘 숙지해야 함
Comments