안정된 인터페이스 만들기
클래스는 C++의 기본 추상화 단위다.
클래스를 작성할 때
추상화 원칙을 적용하여 인터페이스와 구현을 최대한 분리하는 것이 좋다.
특히 데이터 멤버를 private로 지정하고
게더와 세더를 제공하는 것이 바람직하다.
인터페이스 클래스와 구현 클래스
앞서 설명한 기준과 바람직한 설계 원칙을 적용하더라도
C++언어와 추상화 원칙에 잘 맞지않는 부분이 있다.
C++에서는 public 인터페이스와
private(또는 protected) 데이터 멤버 및 메서드를
모두 클래스 정의에 작성하기 때문에
클래스 내부 구현사항이 클라이언트에 어느 정도 노출될 수밖에 없다.
그러므로 비 public 메서드나 데이터 멤버를 클래스에 추가할 때마다
이 클래스를 사용하는 클라이언트 코드를
매번 다시 컴파일해야 하는 단점이 있다.
프로젝트가 커질수록 이 작업에 대한 부담이 커진다.
다행히 인터페이스를 보다 간결하게 구성하고
구현 세부사항을 모두 숨겨서
인터페이스를 안정적으로 유지하는 방법도 있다.
대신 작성할 코드도 좀 늘어난다.
기본 원칙은 작성할 클래스마다
인터페이스 클래스와 구현 클래스를 따로 정의하는 것이다.
구현 클래스는 우리가 흔히 작성하는 클래스 코드를 말한다.
인터페이스 클래스는 구현 클래스와 똑같이
public 메서드를 제공하되
구현 클래스 객체에 대한 포인터를 갖는 데이터 멤버 하나만 정의한다.
이를 핌플 이디엄 혹은 핌플 구문 또는 브릿지 패턴이라 부른다.
인터페이스 클래스 메서드는
단순히 구현 클래스 객체에 있는 동일한 메서드를 호출하기만 한다.
그러면 코드가 변해도 public 메서드로 구성된
인터페이스 클래스는 영향을 받지 않는다.
따라서 다시 컴파일할 시간이(일이) 줄어든다.
이렇게 정의된 인터페이스 클래스를
사용하는 클라이언트는 구현 코드만 변경되었을 때
소스를 다시 컴파일할 필요가 없다.
여기서 유의할 점은 인터페이스 클래스에 존재하는 유일한 데이터 멤버를
구현 클래스에 대한 포인터로 정의해야
제대로 효과를 발휘한다는 것이다.
데이터 멤버가 포인터가 아닌 값이면
구현 클래스가 변경될 때 마다 다시 컴파일해야 한다.