시스템 의 component 의 구성 + interaction 의 fundamental pattern. 매 codebase 의 first read 의 shortcut. 매 wrong style = 매 매 fight 매 month. 선택 기준 = team + scale + change frequency.
📖 핵심
매 5 가지 major style
1. Layered (계층형)
매 horizontal layer: Presentation → Business → Data.
매 strict downward dependency.
✅ 매 simple. ✅ 매 entry-level.
❌ 매 cross-cutting concern (logging, auth) 의 awkward.
❌ 매 layer 의 leak 의 architecture 의 부패.
2. Clean Architecture (Uncle Bob)
매 entity / use case 의 center.
매 framework / DB 의 outer layer (adapter).
매 dependency 의 inward.
✅ 매 testable, framework-independent.
❌ 매 boilerplate (port + adapter).
3. Hexagonal (Ports & Adapters)
매 Clean 의 변형.
매 input port (use case) + output port (repository).
✅ 매 testable. ✅ 매 swap-able tech.
4. DDD (Domain-Driven Design)
매 module 의 Bounded Context.
매 ubiquitous language.
매 Entity / Value Object / Aggregate.
✅ 매 complex business.
❌ 매 simple CRUD 의 over-engineering.
5. Microservices
매 small + independent service.
매 single business capability.
✅ 매 scale + team autonomy.
❌ 매 distributed complexity (network, data consistency, observability).
6. Event-Driven (EDA)
매 message broker (Kafka, RabbitMQ).
매 producer + consumer 의 async.
✅ 매 decoupling. ✅ 매 scale.
❌ 매 ordering / debugging 어려움.
7. Serverless
매 FaaS (Lambda).
매 stateless function.
✅ 매 cost (idle 0).
❌ 매 cold start. 매 vendor lock-in.
매 trade-off matrix
Style
Complexity
Scale
Team
Cost
Monolith
Low
Low-Mid
Small
Low
Layered
Low
Mid
Small-Mid
Low
Clean
Mid
Mid
Mid
Mid
DDD
High
Mid-High
Mid-Large
High
Microservices
High
High
Large
High
EDA
High
Very High
Mid-Large
Mid
Serverless
Mid
Auto
Small-Mid
Variable
매 architecture drift
매 time 의 codebase 가 design 에서 멀어짐.
매 layer violation 의 build-time check (tsc-strict, archunit, dependency-cruiser).
// 매 input port
interfaceCreateOrder{execute(cmd: CreateOrderCommand):Promise<OrderId>;}// 매 output port
interfaceOrderRepository{save(o: Order):Promise<void>;}interfacePaymentGateway{charge(amount: Money):Promise<TxId>;}classCreateOrderHandlerimplementsCreateOrder{constructor(privaterepo: OrderRepository,privatepayment: PaymentGateway){}asyncexecute(cmd: CreateOrderCommand){constorder=Order.create(cmd);consttx=awaitthis.payment.charge(order.total);order.confirmPayment(tx);awaitthis.repo.save(order);returnorder.id;}}