--- id: wiki-2026-0508-객체-지향-소프트웨어-아키텍처-설계 title: 객체 지향 소프트웨어 아키텍처 설계 category: 10_Wiki/Topics status: verified canonical_id: self aliases: [OO architecture, OOA/D, Object-Oriented Architecture] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [oop, architecture, design, ddd] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: python framework: ddd --- # 객체 지향 소프트웨어 아키텍처 설계 ## 매 한 줄 > **"매 behavior + state 의 cohesive object 의 cluster"**. 매 OO architecture 의 system 의 collaborating object 의 graph 의 model — 매 modern stack 의 DDD + Clean/Hexagonal + SOLID 의 layered. ## 매 핵심 ### 매 Layered architecture - **Domain**: 매 entity, value object, aggregate root. - **Application**: 매 use case, 매 thin orchestration. - **Infrastructure**: 매 DB, queue, external API adapter. - **Interface**: 매 HTTP, CLI, gRPC. - **Rule**: 매 dependency 의 inward 의 only (Clean Architecture). ### 매 Building blocks (DDD) - **Entity**: identity 의 have (User#42). - **Value object**: identity 의 X, immutable (Money(100, USD)). - **Aggregate**: consistency boundary, 매 root 의 only 의 외부 의 expose. - **Repository**: aggregate 의 persist abstraction. - **Service**: stateless behavior 의 cross-aggregate. - **Event**: aggregate state change 의 broadcast. ### 매 Design principles - **SOLID**: SRP, OCP, LSP, ISP, DIP. - **Composition over inheritance**: 매 has-a > is-a. - **Tell, don't ask**: 매 behavior 의 object 의 push. - **Law of Demeter**: 매 don't talk to strangers. ### 매 응용 1. E-commerce checkout (Order aggregate). 2. Banking transfer (Account + Transaction). 3. SaaS multi-tenant (Tenant boundary). 4. Game state machine. ## 💻 패턴 ### Aggregate root + repository (Python) ```python from dataclasses import dataclass, field from decimal import Decimal from uuid import UUID, uuid4 @dataclass(frozen=True) class Money: # value object amount: Decimal currency: str def __add__(self, o: "Money") -> "Money": if self.currency != o.currency: raise ValueError return Money(self.amount + o.amount, self.currency) @dataclass class OrderLine: sku: str qty: int price: Money class Order: # aggregate root def __init__(self, id: UUID, lines: list[OrderLine]): self.id = id self._lines = lines self._events: list = [] def add_line(self, line: OrderLine) -> None: if any(self.id == "shipped" for l in self._lines): raise RuntimeError self._lines.append(line) self._events.append(("LineAdded", line)) def total(self) -> Money: return sum((l.price for l in self._lines), Money(Decimal(0), "USD")) class OrderRepo: # abstraction (port) def get(self, id: UUID) -> Order: ... def save(self, order: Order) -> None: ... ``` ### Hexagonal port + adapter ```python from typing import Protocol class PaymentGateway(Protocol): # port def charge(self, amount: Money, token: str) -> str: ... class StripeAdapter: # adapter def charge(self, amount: Money, token: str) -> str: return stripe.Charge.create(amount=int(amount.amount * 100), source=token).id class CheckoutService: # application def __init__(self, orders: OrderRepo, payments: PaymentGateway): self._orders, self._payments = orders, payments def checkout(self, order_id: UUID, token: str) -> str: order = self._orders.get(order_id) return self._payments.charge(order.total(), token) ``` ### Domain event + handler ```python from blinker import signal order_placed = signal("order_placed") @order_placed.connect def send_email(sender, order: Order): mailer.send(order.customer_email, "Receipt", order.total()) ``` ### Strategy via composition ```python class ShippingPolicy(Protocol): def cost(self, order: Order) -> Money: ... class FlatRate: def cost(self, order): return Money(Decimal(5), "USD") class WeightBased: def cost(self, order): return Money(Decimal(order.weight() * 0.5), "USD") # inject, not inherit class Cart: def __init__(self, shipping: ShippingPolicy): self._shipping = shipping ``` ### Bounded context boundary ``` [Sales Context] [Shipping Context] Order(customer, lines) --→ Shipment(orderId, address) (own model, own DB) (own model, own DB) ↕ ↕ Anti-Corruption Layer (translate DTOs) ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Complex business rules | DDD aggregate | | CRUD + thin logic | Active Record / transaction script | | Multi-team scale | Bounded context split | | External I/O isolation | Hexagonal port/adapter | | Cross-cutting policy | Decorator / middleware | **기본값**: Clean Architecture + DDD lite + Hexagonal port. ## 🔗 Graph - 부모: [[Software Architecture]] · [[Object-Oriented-Programming]] - 변형: [[Domain-Driven Design]] · [[Hexagonal Architecture]] · [[Clean Architecture]] - 응용: [[Microservices]] · [[CQRS]] · [[Event Sourcing]] - Adjacent: [[SOLID]] · [[Refactoring_Best_Practices]] · [[Bounded Context]] ## 🤖 LLM 활용 **언제**: aggregate boundary suggestion, code → DDD pattern mapping, layer violation detection. **언제 X**: 매 over-engineering trivial CRUD — 매 LLM 의 DDD 의 over-prescribe 의 tendency, 의 push back. ## ❌ 안티패턴 - **Anemic domain**: 매 getter/setter only data class + service 의 logic, 의 behavior 의 entity 의 push. - **God aggregate**: 매 한 aggregate 의 entire system, 의 split. - **Leaky abstraction**: 매 ORM model 의 domain 의 exposure, 의 separate. - **Inheritance for reuse**: 매 deep hierarchy, 의 composition. - **Layer skipping**: 매 controller → repository 직접, 의 application service 의 통과. ## 🧪 검증 / 중복 - Verified (Evans "DDD" 2003, Vernon "Implementing DDD", Martin "Clean Architecture"). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — full OO architecture entry, DDD + Hexagonal patterns |