인터페이스는 호출자가 필요한 최소 모양을 고정한다

구현체 목록을 먼저 만들지 않는다. 상위 로직이 실제로 호출하는 능력을 좁은 계약으로 뽑고 조립 지점에서 구현을 선택한다.

1

호출자 요구

processor → logger.log() 쓰는 능력만 추출

구현체 전체 API가 아니라 소비자의 필요에서 시작한다.

2

좁은 계약

interface Logger {   log(message: string): void }

필수 멤버의 이름과 타입만 공개한다.

3

구조적 호환

ConsoleLogger FileLogger FakeLogger

필요한 모양을 가지면 같은 계약 위치에 들어간다.

4

조립 지점 선택

new Processor(logger) production ↔ test

호출 코드를 바꾸지 않고 실제 구현과 fake를 교체한다.

implements

컴파일 시 모양 검사

클래스 타입이나 메서드 추론을 바꾸지 않고 계약 충족 여부만 확인한다.

runtime

인터페이스는 값이 아님

실행 시에는 factory·객체·DI token 중 하나가 구현체를 제공해야 한다.

교체 가능성 테스트 FakeLogger를 주입해도 Processor 코드가 그대로라면 경계가 작동한다.