Abstract Interface

추상 클래스 호출 계약

순수 가상 함수는 파생 클래스가 채워야 할 행동을 선언한다. 추상 타입이 작을수록 테스트와 교체가 쉬워진다.

01

호출자가 필요한 말만 남긴다

구체 타입의 편의 함수까지 인터페이스에 넣으면 모든 구현체가 부담을 진다.

02

소멸 계약을 둔다

인터페이스 포인터로 객체를 삭제할 수 있으면 virtual destructor를 반드시 둔다.

03

테스트 대역 생성

외부 시스템과 분리하려면 추상 타입 뒤에 fake 구현을 쉽게 붙일 수 있어야 한다.

small
좁은 표면 함수 수가 적을수록 구현체와 테스트가 단순해진다.
인터페이스 분리 원칙과 맞닿아 있다.
state
상태 없는 계약 데이터 멤버가 들어가면 구현 방식까지 공유하게 된다.
순수 인터페이스는 가볍다.
default impl
공통 흐름 일부 virtual에 기본 구현을 둘 수 있지만 확장 지점을 흐릴 수 있다.
템플릿 메서드는 신중히 쓴다.
factory
구체 타입 숨김 unique_ptr<Interface> 반환으로 생성과 사용을 분리한다.
소유권이 보인다.

함수 수 · 소멸자 · 대체 구현 점검

함수 수 구현체가 억지로 빈 함수를 만들 정도로 인터페이스가 큰가.
소멸자 인터페이스 타입으로 삭제될 가능성에 대비했는가.
대체 구현 테스트에서 작은 fake 구현으로 경계를 대체할 수 있는가.

교체 가능한 경계

class FileSystem {
public:
    virtual ~FileSystem() = default;
    virtual std::string read_text(std::filesystem::path path) = 0;
};