사전 인터페이스
개념

인터페이스

gabury1고친 사람 github-actions[bot]

인터페이스는 두 쪽이 맞닿는 경계에서 무엇을 주고받을지 미리 못 박아 둡니다. 그래서 부르는 쪽은 상대의 속을 몰라도 상대를 부릅니다. 이 낱말은 여러 분야에서 쓰입니다. 프로그래밍 언어가 두는 interface 선언도, 컴퓨터가 망에 붙는 접점도 모두 이 뜻입니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 두 쪽 사이에 그어 둔 약속입니다. 자판기 앞면이 그렇습니다. 동전을 넣고 버튼을 누르면 음료가 나온다는 약속만 알면 됩니다. 안에서 어떻게 꺼내 오는지는 몰라도 됩니다.

왜 이렇게 하나 — 약속이 없으면 부르는 쪽이 상대의 속을 다 알아야 합니다. 그러면 상대가 속을 고칠 때마다 부르는 쪽도 따라서 고쳐야 합니다.

어떻게 도나

  1. 주고받을 것의 이름과 모양을 먼저 정해 적어 둡니다
  2. 한쪽이 그 약속을 지키는 실물을 만듭니다
  3. 다른 쪽은 약속만 보고 부릅니다. 실물이 무엇인지는 묻지 않습니다

대가 — 한 번 내건 약속은 마음대로 못 바꿉니다. 고치는 순간 그 약속에 기대던 쪽이 모두 깨집니다. 약속을 거치느라 한 겹이 더 생겨서 코드를 따라 읽기도 번거로워집니다.

상세

어느 분야에서 쓰이든 이 낱말이 공통으로 가리키는 것부터 세웁니다. 그 위에서 실무가 제일 자주 만나는 두 뜻인 프로그래밍 언어의 인터페이스와 네트워크 인터페이스를 따라갑니다. 글에 나온 「인터페이스」가 어느 뜻인지 가르는 단서로 끝냅니다.

맞닿는 경계의 약속

벽에 붙은 콘센트에는 구멍 두 개의 모양과 간격, 흐르는 전기의 세기가 정해져 있습니다. 그 약속을 지키는 플러그라면 선풍기든 노트북 충전기든 그대로 꽂힙니다.

인터페이스는 이 콘센트처럼 두 쪽이 만나는 경계에서 지킬 것을 적어 둔 약속입니다. 무엇을 부를 수 있고, 무엇을 넘겨야 하고, 무엇이 돌아오는지를 정합니다. 그 약속만 지키면 안쪽을 어떻게 만들었는지는 아무도 묻지 않습니다.

약속 자체와 그 약속을 지키는 실물은 다릅니다. 실물 쪽을 구현이라고 부릅니다. 약속 하나에 구현은 여럿일 수 있습니다. 그 여럿은 서로 갈아 끼울 수 있습니다.

flowchart TD
    C["부르는 쪽"] --> I["인터페이스 · 약속"]
    I --> A["구현 하나"]
    I --> B["구현 둘"]

부르는 쪽의 화살표는 인터페이스에서 멈춥니다. 그 아래 구현이 하나든 둘이든 부르는 코드는 손대지 않아도 됩니다. 이것이 인터페이스가 주는 것의 전부입니다.

인터페이스가 없으면

약속을 따로 두지 않으면 부르는 쪽이 상대를 속까지 알고 써야 합니다. 그러면 둘이 하나처럼 엉겨서 따로 움직일 수 없게 됩니다. 이렇게 엉긴 정도를 결합도라고 부릅니다.

엉겼을 때와 약속을 사이에 두었을 때가 이렇게 갈립니다.

약속이 없을 때 약속이 있을 때
상대가 속을 고치면 부르는 코드도 같이 고쳐야 한다 속이 바뀌어도 약속이 그대로면 부르는 코드는 안 건드린다
상대를 다른 것으로 갈아 끼울 수 없다 약속을 지키는 다른 실물로 갈아 끼운다
상대가 다 만들어질 때까지 기다려야 한다 약속을 먼저 정하고 양쪽이 따로 만든다

표의 오른쪽 셋은 같은 한 가지에서 나옵니다. 부르는 쪽이 아는 것을 약속까지로 줄였기 때문입니다. 아는 것이 적을수록 상대가 바뀌어도 덜 흔들립니다.

언제 두고 언제 안 두나

인터페이스는 공짜가 아닙니다. 약속을 하나 세우면 읽는 사람은 약속과 구현 두 군데를 오가야 합니다. 바꿀 일이 생기면 양쪽을 맞춰 고쳐야 합니다.

그래서 구현이 하나뿐이고 바뀔 낌새도 없으면 약속을 따로 세우지 않습니다. 세워 봐야 겹만 하나 늡니다. 갈아 끼울 일은 오지 않습니다. 구현이 둘째로 생겼을 때 뽑아내도 늦지 않습니다.

반대로 경계를 넘는 곳에는 미리 세워 둡니다. 다른 팀이 만드는 쪽을 부를 때, 프로세스나 기계를 건너 부를 때, 시험할 때만 가짜 구현으로 바꿔 끼워야 할 때가 그렇습니다. 이런 경계는 약속을 안 적어도 이미 있습니다. 적어 두지 않으면 양쪽이 각자 머릿속에 서로 다른 약속을 갖게 됩니다.

언어가 두는 인터페이스

프로그래밍 언어 가운데는 이 약속을 코드로 적어 둘 문법을 주는 것이 있습니다. 자바의 interface 선언이 그렇습니다. 어떤 타입이 갖춰야 할 메서드의 이름과 인자와 반환값만 적습니다. 몸통은 비워 둡니다.

Java
interface Store {  // 약속만 적는다
    String get(String key);  // 몸통이 없다
}

이 선언은 「키를 주면 문자열을 돌려주는 get 이 있다」까지만 말합니다. 그 문자열을 어디서 어떻게 꺼내 오는지는 한 글자도 적지 않습니다.

약속을 지키는 타입은 몸통을 채워 넣습니다. 메모리에서 꺼내는 타입을 하나 만듭니다. 데이터베이스에서 꺼내는 타입을 또 하나 만들 수 있습니다. 둘 다 Store 라는 같은 약속을 지킵니다.

Java
Store s = new MemoryStore();
s.get("apple");     // "사과"

첫 줄만 데이터베이스 쪽 타입으로 바꾸면 둘째 줄은 그대로 돕니다. 부르는 코드가 아는 이름이 Store 하나뿐이라서 그렇습니다.

컴파일러는 약속을 지키겠다고 밝힌 타입이 메서드를 다 갖췄는지 확인합니다. 하나라도 빠지면 컴파일이 안 됩니다. 그래서 언어의 인터페이스는 읽어 보라고 적어 둔 문서가 아니라 기계가 검사하는 규칙입니다.

이 약속은 컴파일이 끝난 뒤에도 남습니다. 클래스 파일에는 그 타입이 어떤 인터페이스를 구현했는지가 목록으로 적혀 있습니다. 그래서 프로그램이 도는 중에도 눈앞의 값이 그 약속을 지키는지 물어볼 수 있습니다.

약속을 맺는 방법은 언어마다 갈립니다. 자바는 구현하는 쪽이 「나는 이 약속을 지킨다」고 이름을 대어 밝혀야 합니다. Go 는 밝히지 않아도 메서드의 이름과 모양이 맞으면 그 인터페이스를 만족한 것으로 봅니다. 뒤쪽 방식을 구조적 타이핑이라고 부릅니다.

네트워크 인터페이스

망에 붙어 데이터를 주고받는 기계 한 대를 노드라고 부릅니다. 노드가 망에 붙는 접점이 네트워크 인터페이스입니다. 랜 카드 하나가 접점 하나입니다. 운영체제는 접점마다 eth0 같은 이름을 붙여 다룹니다.

주소는 노드가 아니라 이 접점에 붙습니다. 인터넷에서 쓰는 IP 주소(Internet Protocol address, 인터넷 프로토콜 주소)가 그렇습니다. 접점이 둘인 기계는 주소도 둘입니다. 접점 하나가 주소를 여럿 달 수도 있습니다.

flowchart TD
    N["노드 · 기계 한 대"]
    N --> E0["인터페이스 eth0"]
    N --> E1["인터페이스 eth1"]
    E0 --> A1["주소 A"]
    E0 --> A2["주소 B"]
    E1 --> A3["주소 C"]

그림에서 주소는 기계가 아니라 그 아래 인터페이스에 매달립니다. 그래서 같은 기계라도 어느 접점으로 찾아가느냐에 따라 쓰는 주소가 달라집니다.

망에 안 붙는 접점도 있습니다. lo 라고 부르는 루프백(되돌이) 인터페이스는 자기가 보낸 것을 자기가 받는 데만 씁니다.

이름이 같은 것은 우연이 아닙니다. 네트워크 인터페이스도 기계와 망이 맞닿는 경계입니다. 그 경계에서 무엇을 어떤 모양으로 주고받을지가 정해져 있습니다.

그 밖에 이 낱말이 붙는 곳

사람과 기계가 맞닿는 경계는 사용자 인터페이스라고 부릅니다. 줄여서 UI(User Interface)라고 씁니다. 화면과 버튼이 그 경계에 놓인 것입니다.

기계 부품끼리 맞닿는 경계에도 같은 낱말을 씁니다. USB(Universal Serial Bus, 범용 직렬 버스)는 꽂는 구멍의 모양과 그 안에서 오가는 신호를 함께 정해 둔 인터페이스입니다.

프로그램이 다른 프로그램에 내거는 약속에는 따로 이름이 붙어 있습니다. API(Application Programming Interface, 응용 프로그래밍 인터페이스)입니다. 이름 끝에 인터페이스가 그대로 들어 있습니다.

어느 뜻으로 쓰였는지 가르는 단서

낱말만으로는 어느 뜻인지 안 갈립니다. 옆에 붙은 말을 보면 대개 갈립니다.

옆에 나오는 말 뜻
타입 · 메서드 · 구현 · 컴파일 언어가 두는 인터페이스
주소 · 패킷 · 랜 카드 · eth0 네트워크 인터페이스
화면 · 버튼 · 사용자 · 디자인 사용자 인터페이스
케이블 · 단자 · 신호 · 규격 하드웨어 인터페이스

어느 뜻이든 바닥은 같습니다. 둘이 맞닿는 경계가 있습니다. 그 경계에서 지키기로 한 약속이 있습니다.

관련 항목

인터페이스와 짝을 이루는 설계 개념

구현 · 추상화 · 캡슐화 · 정보 은닉 · 결합도 · 응집도 · 관심사 분리 · 모듈

인터페이스 선언을 문법으로 두는 언어

자바 · Go · C++ · TypeScript · Rust · Kotlin

인터페이스와 이웃한 타입 체계 개념

구조적 타이핑 · 덕 타이핑 · 추상 클래스 · 다형성 · 제네릭 · 시그니처 · 클래스 파일

프로그램 사이의 경계를 정하는 규약

API · ABI · 프로토콜 · 스키마 · 계약 · 표준 · 상호운용성

네트워크 인터페이스에 붙는 주소와 장비

IP 주소 · MAC 주소 · 노드 · 랜 카드 · 루프백 인터페이스 · 멀티홈드 호스트 · 네트워크

사람과 기계의 경계를 다루는 분야

사용자 인터페이스 · 명령줄 인터페이스 · 프론트엔드 · 사용자 경험 · 접근성

인터페이스를 지렛대로 쓰는 설계 패턴

어댑터 패턴 · 전략 패턴 · 의존성 주입 · 의존성 역전 원칙 · 인터페이스 분리 원칙 · 포트와 어댑터 · 목 객체

다른 이름: interface