우리가 매일 사용하는 스마트폰 충전기를 생각해보자. 최신 스마트폰은 대부분 C타입 포트를 가지고 있다. 소프트웨어 설계 관점에서 이 둘을 명확히 구분해 보면, 포트(Port)는 스마트폰의 C타입 단자에 해당하는 구멍이고, 어댑터(Adapter)는 충전기, 외장 하드 등 포트에 꽂아서 실제 기능을 제공하는 구현체다.
클린 아키텍처는 외부 기술(인프라)로부터 소프트웨어가 풀고자 하는 문제를 해결하는 논리인 비즈니스 로직(도메인)을 지켜내는데(ref1), 도메인 계층과 인프라 계층 사이의 의존성을 처리하는 방법이 육각형 아키텍처(hexagonal architecture)가 제안하는 포트-어댑터 패턴에서 영감을 받았다(ref2). 클린 아키텍처에서 자주 등장하는 Gateway(또는 Repository)가 바로 이 포트-어댑터 쌍이다(ref3).
예를 들어, 아래와 같은 코드가 있다고 해 보자. C타입 포트를 파이썬으로 모방해 본 것이다.
class CtypeGateway(Protocol):
def supply_power(self, voltage: float, amperage: float) -> None:
pass
C타입 충전 포트(어답터 인터페이스라고도 부른다) CtypeGateway
는 ‘포트’다. 포트는 도메인 계층에 위치한다. 실제로 어떤 충전기가 이 포트에 꽂힐지는 알지 못한다. 실제 기능을 구현하는 것이 ‘어댑터’로서의 Gateway다.
class SamsungCtypeCharger(CtypeGateway):
def supply_power(self, voltage: float, amperage: float):
print(f"삼성 45W 급속 충전")
class AppleCtypeCharger(CtypeGateway):
def supply_power(self, voltage: float, amperage: float):
print(f"애플 20W 충전")
Gateway는 이처럼 외부 시스템과의 통신을 추상화한 포트다.
Repository는 그 중에서도 데이터 저장소와의 통신에 특화된 Gateway의 한 형태라고도 해석할 수 있다. 마치 USB-C에 연결할 수 있는 수많은 기기 중에서 외장 SSD가 '데이터 저장'이라는 특수한 목적을 가진 것처럼 말이다.
class CtypeGateway(Protocol):
def get_data(self, ...):
pass
def write_data(self, data):
pass
class SamsungCtypeExternalDisk(CtypeGateway):
def get_data(self, ...):
print(f"데이터 전송 중")
def write_data(self, data):
print(f"데이터 전송 중")
parse me : 언젠가 이 글에 쓰이면 좋을 것 같은 재료을 보관해 두는 영역입니다.
None
from : 과거의 어떤 원자적 생각이 이 생각을 만들었는지 연결하고 설명합니다.
supplementary : 어떤 새로운 생각이 이 문서에 작성된 생각을 뒷받침하는지 연결합니다.
None