[오브젝트] 부록 A 계약에 의한 설계

인터페이스만으로 객체의 행동에 관한 다양한 관점을 전달하기 어렵다.
명령의 부수효과를 쉽고 명확하게 표현할 수 있는 커뮤니케이션 수단이, 계약에 의한 설계이다.
여기서 중요한 것은 코드가 아니라, 개념이다.

01 협력과 계약

부수 효과를 명시적으로

일반적인 정합성 체크 로직은 코드의 구현 내부에 숨겨져있어 실제로 코드를 분석하지 않는 한 정확하게 파악하기 어렵다.

하지만, Code Contracts 와 같이 계약에 의한 설계를 지원하는 라이브러리나 언어들은 일반 로직과 구분할 수 있도록 제약 조건을 명시적으로 표현하는 것이 가능하다.

02 계약에 의한 설계

버트란드 마이어가 제시한 계약은, 사람들 사이의 계약과 유사하다. 계약은 협력에 참여하는 두 객체 사이의 의무와 이익을 문서화한 것이다.

  1. 협력에 참여하는 객체는 계약으로부터 이익을 기대하고 이익을 얻기위해 의무를 이행한다.
  2. 협력에 참여하는 객체의 이익과 의무는 객체의 인터페이스 상에 문서화된다.

의도를 드러내는 인터페이스는 오퍼레이션의 시그니처만으로 어느 정도 클라이언트와 서버가 협력을 위해 수행해야하는 제약 조건을 명시한다.

계약은 여기서 한 걸음 더 나아간다. 서버는 자신이 처리할 수 있는 범위의 값들을 클라이언트가 전달할 것으로 기대한다. 클아이언트는 자신이 원하는 값을 서버가 반환할 것이라고 예상한다. 클아이언트는 메세지 전송 전과 후의 서버 상태가 정상일 것이라고 기대한다.

  1. 사전 조건
    메서드가 호출되기 위해 만족되어야하는 조건. 클라이언트의 의무
  2. 사후 조건
    메서드가 실행된 후에 클라이언트에게 보장해야하는 조건. 서버의 의무
  3. 불변식
    항상 참이라고 보장되는 서버의 조건
사전 조건

클라이언트가 사전 조건을 만족시키지 못하면, 메서드는 최대한 빨리 실패해서 클라이언트에게 버그가 있다는 사실을 알린다.

사후 조건

다음 세 용도로 사용된다.

  1. 인스턴스 변수의 상태가 올바른지 서술하기 위해
  2. 메스드에 전달된 파라미터의 값이 올바르게 변경됐는지를 서술하기 위해
  3. 반환값이 올바른지를 서술하기 위해
불변식

객체의 내부 상태와 관련이 있다.

메서드 실행 중에는 객체의 상태가 불안정한 상태로 빠질 수 있기 때문에 불변식을 만족시킬 필요가 없지만, 메서드 실행 전과 종료 후에는 항상 불변식을 만족해야한다.

03 계약에 의한 설계와 서브타이핑

리스코프 치환 원칙은, 슈퍼타입의 인스턴스와 협력하는 클라이언트의 관점에서 서브타입의 인스턴스가 슈퍼타입을 대체하더라도 협력에 지장이 없어야 한다는 것을 의미한다.

따라서 서브타입이 리스코프 치환 원칙을 만족하기 위해서는, 클라이언트와 슈퍼타입 간에 체결된 계약을 준수해야한다.

계약 규칙
  1. 서브타입에 더 강력한 사전 조건을 정의할 수 없다.
    계약서에 명시된 의무보다 더 많은 의무를 짊어져야한다는 사실을 납득하는 클라이언트는 없다.

  2. 서브타입에 더 완화된 사후 조건을 정의할 수 없다.
    계약서에 명시된 이익보다 더 적은 이익을 받게 되는 사실을 납득하는 클라이언트는 없다.

  3. 슈퍼타입의 불변식은 서브타입에서도 유지되어야 한다.
    메서드 실행 중에는 불변식을 만족시키지 않아도 되지만, 메서드 실행 전과 후에는 만족해야한다.

가변성 규칙
  1. 서브타입은 슈퍼타입이 발생시키는 예외와 다른 타입의 예외를 발생시켜서는 안된다.
    클라이언트는 Bird 의 인스턴스에 fly 메세지를 전송했을 때, UnsupportedOperationException 예외를 기대하지 않는다.

  2. 서브타입의 리턴타입은 공변성을 가져야한다.
    리턴 타입 공변성 : 부모 클래스에서 구현된 메서드를 자식 클래스에서 오버라이딩할 때 부모 클래스에서 선언한 반환 타입의 서브타입으로 지정할 수 있는 특성

  3. 서브타입의 메서드 파라미터는 반공변성을 가져야 한다.
    파라미터 타입 반공병성 : 부모 클래스에서 구현된 메서드를 자식 클래스에서 오버라이딩할 때 파라미터 타입을 부모 클래스에서 사용한 파라미터의 슈퍼타입으로 지정할 우 있는 특성


오브젝트 <조영호>

Comments