"매 'what' 매 'how' 의 분리". Implementation separation 매 interface (contract) 매 implementation (mechanism) 매 명시적 분리 — 매 dependency inversion, ports-and-adapters, hexagonal architecture 의 core idea. 매 testability, swappability, evolution 매 enable.
매 핵심
매 Why separate
Test: 매 fake/mock 매 swap-in.
Swap: 매 Postgres → DynamoDB 매 caller code unchanged.
Boundary: 매 layer/module 매 명확.
Parallel work: 매 interface freeze → 매 team 매 parallel implementation.
매 Levels of separation
Interface keyword (Java, C#, Go, TypeScript): 매 syntax 매 enforce.
Abstract base class (Python, C++): 매 ABC, virtual.
Protocol/structural typing (Python typing.Protocol, TypeScript): 매 duck typing 매 static check.
Trait (Rust): 매 zero-cost.
Module boundary (Haskell .hs-boot, OCaml .mli): 매 module-level.
매 응용
Repository pattern: 매 UserRepo interface, 매 PgUserRepo impl.
Strategy pattern: 매 algorithm 매 swap.
Adapter (port): 매 external service 매 wrap.
Test doubles: 매 InMemory* impl.
💻 패턴
TypeScript — port + adapter
// Port (domain owns this)
exportinterfaceUserRepo{findById(id: string):Promise<User|null>;save(u: User):Promise<void>;}// Adapter (infrastructure)
exportclassPgUserRepoimplementsUserRepo{constructor(privatedb: Pool){}asyncfindById(id: string){constr=awaitthis.db.query('select * from users where id=$1',[id]);returnr.rows[0]?mapUser(r.rows[0]):null;}asyncsave(u: User){awaitthis.db.query('insert into users ...',[u.id,u.name]);}}// In-memory test double
exportclassInMemoryUserRepoimplementsUserRepo{privatemap=newMap<string,User>();asyncfindById(id: string){returnthis.map.get(id)??null;}asyncsave(u: User){this.map.set(u.id,u);}}
Python Protocol (structural)
fromtypingimportProtocolclassNotifier(Protocol):defsend(self,to:str,msg:str)->None:...classEmailNotifier:defsend(self,to:str,msg:str)->None:smtp.sendmail(...)classSlackNotifier:defsend(self,to:str,msg:str)->None:requests.post("https://slack/api",json={"channel":to,"text":msg})defnotify_user(n:Notifier,user_id:str,msg:str)->None:n.send(user_id,msg)# any structural match works
언제: 매 architecture refactor; 매 testability 부족; 매 multiple infra backend; 매 team boundary.
언제 X: 매 single-use script; 매 prototype; 매 only one impl forever.
❌ 안티패턴
IFoo + FooImpl 매 1:1 forever: 매 interface 매 swap/test point 없으면 매 잡음.
Leaky abstraction: 매 interface method 매 SQL string 받음 — 매 impl 의 detail 노출.
Anemic port: 매 CRUD method 만 매 interface — 매 domain logic 매 caller 에 leak.
Adapter 매 domain 의 의존: 매 dep 매 wrong direction.
🧪 검증 / 중복
Verified (Cockburn 2005 "Hexagonal Architecture", Evans DDD, Martin "Clean Architecture", Vernon IDDD).
신뢰도 A.
🕓 Changelog
날짜
변경
2026-05-08
Phase 1
2026-05-10
Manual cleanup — full content (port/adapter, multi-language patterns)