Program Against Abstractions

Program Against Abstractions(추상화에 대하여 프로그래밍하라) 는 소프트웨어 아키텍처 및 설계에서 핵심 원칙 중 하나로, 구체적인 구현체가 아닌 추상화 계층 (인터페이스, 추상 클래스 등) 에 의존해 코드를 작성하는 것을 의미한다. 이 원칙은 시스템의 결합도를 낮추고, 변화에 유연하게 대응할 수 있도록 하며, 유지보수와 테스트, 확장성을 크게 향상시킨다. 객체지향 설계의 DIP(의존성 역전 원칙) 와도 밀접하게 연관되어 있다.

핵심 개념

Program Against Abstractions란 코드를 작성할 때 구체적인 구현체가 아니라, 인터페이스나 추상 클래스 등 추상화 계층에 의존하도록 설계하는 것이다.

Program Against Abstractions의 핵심 개념들:

  1. 추상화 (Abstraction): 구현 세부사항을 숨기고 본질적인 특성만을 노출하는 개념
  2. 구체화 (Concretion): 실제 구현을 포함한 구체적인 클래스나 모듈
  3. 의존성 역전 (Dependency Inversion): 고수준 모듈이 저수준 모듈에 의존하지 않고 추상화에 의존하는 원칙
  4. 인터페이스 (Interface): 구현을 강제하는 계약을 정의하는 추상화 도구
  5. 느슨한 결합 (Loose Coupling): 컴포넌트 간의 의존성을 최소화하는 설계 방식

배경

역사적 배경:

등장 배경:

목적 및 필요성

주요 목적:

  1. 유연성 확보: 구현체 변경 시 클라이언트 코드 수정 최소화
  2. 확장성 향상: 새로운 구현체 추가 시 기존 코드 영향 최소화
  3. 테스트 용이성: Mock 객체를 활용한 단위 테스트 가능
  4. 재사용성 증대: 다양한 구현체와 함께 사용 가능한 코드 작성

필요성:

주요 기능 및 역할

  1. 의존성 관리: 컴포넌트 간 의존성을 추상화 계층으로 관리
  2. 변경 격리: 구현 변경이 다른 컴포넌트에 미치는 영향 차단
  3. 인터페이스 정의: 명확한 계약을 통한 컴포넌트 간 상호작용 정의
  4. 확장성 제공: 새로운 기능 추가 시 기존 코드 변경 최소화

핵심 원칙

  1. 추상화 의존 원칙: 구체적인 클래스가 아닌 추상화에 의존
  2. 인터페이스 분리 원칙: 클라이언트가 사용하지 않는 메서드에 의존하지 않음
  3. 대체 가능성 원칙: 추상화를 구현한 모든 객체는 상호 교체 가능
  4. 단일 책임 원칙: 각 인터페이스는 하나의 명확한 책임만 가짐

주요 원리

graph TD
    A[클라이언트 코드] --> B[추상화 계층]
    B --> C[구현체 A]
    B --> D[구현체 B]
    B --> E[구현체 C]
    
    F[고수준 모듈] --> G[인터페이스]
    H[저수준 모듈] --> G
    
    style B fill:#e1f5fe
    style G fill:#e1f5fe

핵심 원리:

  1. 의존성 역전: 고수준과 저수준 모듈 모두 추상화에 의존
  2. 추상화 안정성: 추상화는 구체화보다 안정적
  3. 계약 우선: 구현보다 인터페이스 계약을 우선시
  4. 느슨한 결합: 컴포넌트 간 직접적인 의존성 제거

작동 원리

sequenceDiagram
    participant Client as 클라이언트
    participant Interface as 인터페이스
    participant Implementation as 구현체
    
    Client->>Interface: 메서드 호출
    Interface->>Implementation: 실제 구현 실행
    Implementation-->>Interface: 결과 반환
    Interface-->>Client: 결과 전달

작동 메커니즘:

  1. 인터페이스 정의: 필요한 기능을 추상 메서드로 정의
  2. 구현체 작성: 인터페이스를 구현하는 구체적인 클래스 작성
  3. 의존성 주입: 클라이언트에 인터페이스 타입으로 구현체 제공
  4. 런타임 바인딩: 실행 시점에 실제 구현체 메서드 호출

작동 원리 및 구조

classDiagram
    class IService {
        <<interface>>
        +execute() : Result
        +validate() : boolean
    }
    
    class ServiceA {
        +execute() : Result
        +validate() : boolean
    }
    
    class ServiceB {
        +execute() : Result
        +validate() : boolean
    }
    
    class Client {
        -service : IService
        +Client(service: IService)
        +performAction() : void
    }
    
    IService <|-- ServiceA
    IService <|-- ServiceB
    Client --> IService
구분구성요소기능역할특징
필수추상화 계층 (Interface/Abstract Class)계약 정의구현체와 클라이언트 간 중개안정적, 변경 빈도 낮음
구현체 (Concrete Implementation)실제 로직 구현비즈니스 로직 처리변경 가능, 교체 가능
클라이언트 (Client)서비스 사용추상화를 통한 기능 호출구현체에 독립적
선택의존성 주입 컨테이너 (DI Container)객체 생성 및 주입의존성 관리 자동화설정 기반, 런타임 관리
팩토리 패턴 (Factory Pattern)객체 생성 추상화구체적인 생성 로직 캡슐화생성 복잡성 숨김
어댑터 패턴 (Adapter Pattern)인터페이스 변환기존 코드와 새 인터페이스 연결레거시 코드 통합

구현 기법

인터페이스 기반 설계

정의: 모든 의존성을 인터페이스로 정의하는 기법
구성: 인터페이스 + 구현체 + 클라이언트
목적: 강한 결합 제거 및 유연성 확보

실제 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 인터페이스 정의
from abc import ABC, abstractmethod

class IPaymentProcessor(ABC):
    @abstractmethod
    def process_payment(self, amount: float, payment_info: dict) -> bool:
        pass

# 구현체들
class CreditCardProcessor(IPaymentProcessor):
    def process_payment(self, amount: float, payment_info: dict) -> bool:
        # 신용카드 결제 로직
        return True

class PayPalProcessor(IPaymentProcessor):
    def process_payment(self, amount: float, payment_info: dict) -> bool:
        # PayPal 결제 로직
        return True

# 클라이언트
class OrderService:
    def __init__(self, payment_processor: IPaymentProcessor):
        self._payment_processor = payment_processor
    
    def complete_order(self, order_amount: float, payment_info: dict):
        return self._payment_processor.process_payment(order_amount, payment_info)

의존성 주입 (Dependency Injection)

정의: 외부에서 의존성을 주입하는 기법
구성: 생성자 주입, 세터 주입, 인터페이스 주입
목적: 객체 생성과 사용의 분리

시스템 구성:

graph LR
    A[DI Container] --> B[Service Registration]
    A --> C[Dependency Resolution]
    A --> D[Lifecycle Management]
    
    E[Constructor Injection] --> F[Client Object]
    G[Interface] --> F
    H[Implementation] --> G

전략 패턴 (Strategy Pattern)

정의: 알고리즘을 캡슐화하고 교체 가능하게 만드는 패턴
구성: Context + Strategy Interface + Concrete Strategies
목적: 런타임에 알고리즘 변경 가능

시나리오: 다양한 할인 정책을 적용하는 쇼핑몰 시스템

장점과 단점

구분항목설명
장점유연성구현체 변경 시 클라이언트 코드 수정 불필요
확장성새로운 구현체 추가가 용이함
테스트 용이성Mock 객체를 활용한 단위 테스트 가능
재사용성동일한 인터페이스로 다양한 구현체 사용
유지보수성변경 영향 범위 최소화
단점복잡성 증가추가적인 추상화 계층으로 인한 복잡성
성능 오버헤드간접 호출로 인한 미미한 성능 저하
과도한 추상화불필요한 인터페이스 생성 가능성
학습 비용초기 설계 시 높은 이해도 요구

도전 과제

도전 과제설명해결책
기존 코드베이스 적용 어려움레거시 코드에 추상화 적용이 어렵고, 직접 의존이 많음점진적 리팩토링, 추상화된 인터페이스 도입으로 결합도 감소
과도한 추상화단순 기능에도 불필요한 인터페이스를 생성하여 오히려 복잡도 증가YAGNI 원칙 적용, 실제 사용 시점 기준으로 추상화 적용 결정
인터페이스 설계의 어려움적절한 책임 분리와 추상화 수준 정의가 어려움도메인 전문가와 협업, 반복적 설계 검토 및 리팩토링
런타임 성능 영향추상화 계층 증가로 호출 성능 저하 발생 가능프로파일링 기반 성능 측정, 성능 중요 구간은 직접 구현 고려

분류에 따른 종류 및 유형

분류 기준분류/유형설명장점단점
추상화 수준고수준 추상화비즈니스 로직 중심 인터페이스변경에 유연, 테스트 용이구현과 거리감 있음
저수준 추상화기술적 세부사항 캡슐화모듈 교체 용이, 유지보수 편리과도시 설계 복잡도 증가
구현 범위단일 책임 인터페이스하나의 역할만 수행SRP(단일 책임 원칙) 준수인터페이스 수 증가
복합 인터페이스관련된 여러 기능 통합관련 기능 일괄 관리응집도 낮으면 결합도 증가
생명 주기정적 인터페이스컴파일 시점에 타입 결정타입 안정성 보장, IDE 지원유연성 낮음
동적 인터페이스런타임 시점에 구조 해석높은 유연성, 빠른 프로토타이핑런타임 오류 위험
타입 정의명시적 인터페이스명확한 계약 정의문서화 및 검증 용이구현 코드 많아짐
제네릭 인터페이스타입 매개변수로 동작 추상화재사용성, 타입 안전성설계 복잡도 증가
타입 시스템덕 타이핑이름이 아닌 구조에 기반한 인터페이스유연한 의존성, 빠른 개발 가능일관성 부족, 추적 어려움

실무 적용 예시

분야적용 사례추상화구현체효과
데이터 액세스Repository PatternIUserRepositoryMySQLUserRepository, MongoUserRepositoryDB 변경 시 비즈니스 로직 보호
외부 서비스 연동Gateway PatternIPaymentGatewayStripeGateway, PayPalGateway결제 서비스 변경 용이
알림 시스템알림 서비스INotificationServiceEmailNotifier, SMSNotifier, PushNotifier다중 알림 채널 지원
로깅 시스템로깅 추상화ILoggerFileLogger, DatabaseLogger, CloudLogger로깅 전략 변경 자유도
캐싱 시스템캐시 추상화ICacheServiceMemoryCache, RedisCache, DistributedCache캐싱 전략 최적화

활용 사례

사례 1: 전자상거래 플랫폼의 주문 처리 시스템

시나리오: 대형 온라인 쇼핑몰에서 다양한 결제 방식 (신용카드, PayPal, 가상계좌, 암호화폐) 과 배송 방식 (일반배송, 택배, 드론배송) 을 지원하는 주문 처리 시스템을 구축

시스템 구성:

graph TB
    subgraph "클라이언트 계층"
        A[OrderController]
    end
    
    subgraph "서비스 계층"
        B[OrderService]
    end
    
    subgraph "추상화 계층"
        C[IPaymentProcessor]
        D[IShippingService]
        E[IInventoryService]
    end
    
    subgraph "구현 계층"
        F[CreditCardProcessor]
        G[PayPalProcessor]
        H[StandardShipping]
        I[ExpressShipping]
        J[DatabaseInventory]
        K[CacheInventory]
    end
    
    A --> B
    B --> C
    B --> D
    B --> E
    C --> F
    C --> G
    D --> H
    D --> I
    E --> J
    E --> K

Workflow:

sequenceDiagram
    participant Customer as 고객
    participant OrderController as 주문컨트롤러
    participant OrderService as 주문서비스
    participant PaymentProcessor as 결제처리기
    participant ShippingService as 배송서비스
    participant InventoryService as 재고서비스
    
    Customer->>OrderController: 주문 요청
    OrderController->>OrderService: processOrder()
    OrderService->>InventoryService: checkAvailability()
    InventoryService-->>OrderService: 재고 확인 결과
    OrderService->>PaymentProcessor: processPayment()
    PaymentProcessor-->>OrderService: 결제 결과
    OrderService->>ShippingService: arrangeShipping()
    ShippingService-->>OrderService: 배송 안내
    OrderService-->>OrderController: 주문 완료 결과
    OrderController-->>Customer: 주문 확인

역할 및 책임:

  1. OrderService: 주문 비즈니스 로직 조율, 추상화된 인터페이스만 사용
  2. IPaymentProcessor: 결제 처리 추상화, 다양한 결제 방식 지원
  3. IShippingService: 배송 서비스 추상화, 배송 방식 선택 유연성
  4. IInventoryService: 재고 관리 추상화, 다양한 데이터 소스 지원

구현 코드 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class OrderService:
    def __init__(self, 
                 payment_processor: IPaymentProcessor,
                 shipping_service: IShippingService,
                 inventory_service: IInventoryService):
        self._payment_processor = payment_processor
        self._shipping_service = shipping_service
        self._inventory_service = inventory_service
    
    def process_order(self, order: Order) -> OrderResult:
        # 재고 확인
        if not self._inventory_service.check_availability(order.items):
            return OrderResult.insufficient_inventory()
        
        # 결제 처리
        payment_result = self._payment_processor.process_payment(
            order.total_amount, order.payment_info)
        if not payment_result.success:
            return OrderResult.payment_failed(payment_result.error)
        
        # 배송 준비
        shipping_result = self._shipping_service.arrange_shipping(
            order.shipping_address, order.items)
        
        return OrderResult.success(payment_result, shipping_result)

실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점

구분고려사항설명권장사항
설계 단계책임 분리각 모듈이 고유한 책임을 가지도록 설계단일 책임 원칙 (SRP) 및 인터페이스 분리 원칙 (ISP) 적용
적절한 추상화 수준과도하거나 부족한 추상화는 설계 복잡성을 증가시킴실제 변경 가능성이 높은 부분에만 추상화 도입
인터페이스 명확성추상화된 메서드는 구체성과 일반성의 균형이 필요도메인 용어 기반의 직관적인 인터페이스 정의
인터페이스 안정성인터페이스 변경 시 영향 범위가 커질 수 있음충분한 도메인 분석 및 의존성 최소화 전략 수립
구현 단계의존성 주입 전략추상 타입에 의존하도록 구성하며, 주입 방식에 따라 유연성이 달라짐생성자 주입을 기본으로 하며, 필요 시 세터/인터페이스 주입 활용
구현체 수 증가 관리다양한 구현체로 인해 관리 포인트 증가 가능DI(Dependency Injection) 컨테이너 및 설정 기반 주입 활용
생명주기 및 스코프 관리인터페이스에 주입된 객체의 생명주기 고려 필요싱글톤, 프로토타입 등 컨테이너 스코프 활용
예외 처리 전략추상화 계층에서 발생하는 예외의 처리 일관성 유지도메인별 커스텀 예외 정의 및 매핑
테스트 단계테스트 용이성 확보추상화는 테스트 대상 분리를 용이하게 함Mock, Stub, Spy 등 테스트 더블 패턴 활용
통합 테스트 전략추상화된 계층을 실제 구현체와 검증 필요TestContainers, Spring Profile 등으로 통합 테스트 구성
운영 단계성능 영향 모니터링추상화로 인한 간접 호출이 성능에 미치는 영향APM(Application Performance Monitoring) 도구로 병목 식별
설정 기반 유연성 확보런타임에 구현체 교체 등 유연한 구성 필요외부 설정 파일, 환경 변수 활용

최적화하기 위한 고려사항 및 주의할 점

구분고려사항설명권장사항
메모리 최적화객체 생성 비용인터페이스 구현체 생성 및 의존성 주입 시 메모리 사용량 증가객체 풀링, 싱글턴 패턴, Lazy Initialization 적용
가비지 컬렉션 영향불필요한 객체가 과도하게 생성되어 GC(Garbage Collection) 압박 유발불변 객체 (Immutable Object), 재사용 전략 도입
실행 성능다형성 및 간접 호출 비용인터페이스/추상 클래스 기반 호출은 직접 호출보다 성능 저하 발생핫스팟 분석 후 성능 민감한 경로에 직접 구현체 사용
인라인 최적화 제한컴파일러 최적화 (인라이닝) 가 추상화로 인해 제한될 수 있음JIT 프로파일 기반 최적화 (PGO: Profile-Guided Optimization) 활용
추상화 구조과도한 추상화불필요한 추상화 계층은 복잡성과 호출 비용 증가KISS 원칙 적용, 필요한 경우에만 추상화 도입
디버깅/추적 어려움추상화가 깊어질수록 문제 원인 분석이 어려움명확한 계층 구조 문서화 및 책임 구분
의존성 관리DI 프레임워크 초기화 비용의존성 주입 (DI: Dependency Injection) 시 생성 및 주입 비용 발생싱글턴 활용, 필요한 경우 Lazy 주입 적용
캐싱 전략구현체별 캐싱각기 다른 구현체가 다른 방식으로 캐싱 처리데코레이터 패턴 활용, 캐싱 로직 분리
리플렉션/메타데이터 캐싱런타임에 발생하는 리플렉션 비용 증가타입 정보 캐싱 등 메타데이터 최적화 적용
네트워크 최적화원격 호출/직렬화 비용분산 시스템 내 인터페이스 호출은 네트워크 오버헤드 발생배치 처리, 비동기 패턴, 효율적 직렬화 (예: Protocol Buffers 등) 적용

주목할 내용 정리

주제항목설명
추상화인터페이스 / 추상 클래스구현을 분리하고 유연한 구조를 제공하며, 변경에 강한 설계를 가능하게 함
설계 원칙DIP (Dependency Inversion Principle)고수준 모듈과 저수준 모듈 모두가 추상화에 의존하도록 설계하는 SOLID 원칙
ISP (Interface Segregation Principle)클라이언트가 사용하지 않는 메서드에 의존하지 않도록 인터페이스를 분리하는 원칙
OCP (Open-Closed Principle)시스템은 확장에는 열려 있고 수정에는 닫혀 있어야 함
디자인 패턴전략 패턴 (Strategy)알고리즘을 캡슐화하여 런타임에 교체 가능하게 만드는 패턴
팩토리 패턴 (Factory)객체 생성 로직을 추상화하여 캡슐화
어댑터 패턴 (Adapter)서로 다른 인터페이스 간의 호환성을 제공하는 연결 패턴
데코레이터 패턴 (Decorator)객체에 기능을 동적으로 추가 가능
아키텍처 패턴계층형 아키텍처계층 간 추상화를 통한 모듈 간 결합도 감소
헥사고날 아키텍처 (Hexagonal)포트와 어댑터를 통해 외부 의존성과 내부 도메인을 분리
클린 아키텍처 (Clean Architecture)의존성의 방향을 내부 비즈니스 로직으로만 향하도록 설계
기술적 구현DI (Dependency Injection)런타임에 외부에서 객체를 주입하여 결합도를 낮추는 기법
IoC (Inversion of Control)객체 생성 및 제어 책임을 프레임워크 또는 컨테이너로 위임
AOP (Aspect-Oriented Programming)로깅, 트랜잭션 등 횡단 관심사를 모듈화
코드 유지보수인프라 분리구현 클래스 교체가 쉬워 테스트 및 유지보수 용이
객체 캡슐화인터페이스 중심 설계클라이언트는 구체 구현이 아닌 추상에 의존하여 시스템의 유연성과 확장성이 증가
적용 분야결제, 로깅, 데이터 접근외부 변화에 강한 시스템 구현에 활용 가능

하위 주제로 분류한 추가 학습 내용

카테고리주제설명
설계 원칙Dependency Inversion Principle고수준 모듈이 저수준 모듈에 의존하지 않도록 추상화 중심으로 설계
GRASP 원칙객체지향 설계를 위한 9 가지 핵심 원칙 (Information Expert, Creator 등)
Law of Demeter최소 지식 원칙으로 객체 간 직접적인 결합 최소화
Hollywood Principle" 우리가 당신을 호출하겠다 " 는 제어 흐름의 역전 원칙
디자인 패턴Factory Pattern객체 생성 책임을 추상화하여 구체 클래스를 감춤
Service Locator Pattern런타임 시점에 서비스 인스턴스를 찾아주는 중앙 레지스트리 패턴
Strategy Pattern알고리즘을 캡슐화하여 런타임에 교체 가능하게 만드는 행동 패턴
Abstract Factory Pattern관련된 객체군을 일관성 있게 생성할 수 있도록 하는 생성 패턴
Proxy Pattern객체 접근을 제어하는 대리자 제공 패턴
구현 기법Dependency Injection (DI)객체 간 의존성을 외부에서 주입받아 결합도를 낮추는 구현 기법
DI 컨테이너Spring IoC, Unity, Autofac 등의 의존성 주입 프레임워크
테스팅테스트 더블 (Test Double)Mock, Stub, Spy, Fake 등을 이용한 테스트 전략
계약 테스트 (Contract Testing)소비자 - 제공자 간 API 계약을 자동 검증하는 테스트 기법
통합 테스트 전략실제 구현체와 외부 시스템을 함께 테스트하는 방법론
성능 최적화객체 풀링 (Object Pooling)객체 생성을 최소화하고 재사용하여 성능을 향상
지연 로딩 (Lazy Loading)실제 필요 시점까지 객체 생성을 지연시켜 리소스 절약

관련 분야별 추가 학습 내용

관련 분야카테고리주제설명
소프트웨어 아키텍처마이크로서비스서비스 간 인터페이스 설계API Gateway, 서비스 메시 등을 통한 추상화
이벤트 기반 아키텍처이벤트 인터페이스 설계이벤트 스키마와 계약 정의
도메인 주도 설계 (DDD)바운디드 컨텍스트도메인별 인터페이스 경계 정의
데이터베이스Repository 패턴데이터 액세스 추상화ORM 과 데이터베이스 독립성
Unit of Work 패턴트랜잭션 추상화비즈니스 트랜잭션과 기술적 트랜잭션 분리
웹 개발MVC 패턴계층 간 인터페이스컨트롤러, 서비스, 레포지토리 계층 분리
RESTful API 설계HTTP 인터페이스 설계리소스 중심의 인터페이스 설계 원칙
클라우드 네이티브서비스 메시서비스 간 통신 추상화Istio, Linkerd 등을 통한 네트워크 추상화
컨테이너 오케스트레이션인프라 추상화Kubernetes API 를 통한 인프라 추상화

주제와 관련하여 추가로 알아야 하거나 학습해야 할 내용들

관련 분야카테고리주제설명
소프트웨어 아키텍처마이크로서비스서비스 간 인터페이스 설계API Gateway, 서비스 메시, 컨트랙트 기반 통신 등
이벤트 기반 아키텍처이벤트 인터페이스 설계이벤트 스키마 정의와 발행/구독 구조 설계
도메인 주도 설계 (DDD)바운디드 컨텍스트도메인별 인터페이스 및 책임 경계 정의
Onion Architecture계층 간 의존성 방향의 제한핵심 도메인을 중심으로 한 계층 분리
Clean Architecture핵심 로직과 인프라 분리의존성 방향을 내부 도메인으로 향하게 함
Microkernel Architecture플러그인 기반 설계유연한 기능 확장을 위한 핵심 - 확장 구조
데이터베이스Repository 패턴데이터 액세스 추상화DB 기술과 비즈니스 로직의 분리
Unit of Work 패턴트랜잭션 추상화여러 DB 연산의 원자성 보장을 위한 단위 처리
웹 개발MVC 패턴계층 간 인터페이스 분리Controller-Service-Repository 계층 구조
RESTful API 설계HTTP 기반 인터페이스 설계리소스 지향 설계, URI, 상태 코드, 메서드 표준화
클라우드 네이티브서비스 메시서비스 간 통신 추상화Istio, Linkerd 등으로 관찰 가능성 및 보안 제어
컨테이너 오케스트레이션인프라 추상화Kubernetes API 및 배포 전략 중심 설계
프레임워크/도구Spring DI의존성 주입 프레임워크IoC 컨테이너를 통한 구성 및 주입 자동화
IoC Container제어의 역전 구현 도구런타임 객체 생성 및 의존성 주입 관리
객체지향 설계Interface-based Design인터페이스 중심 설계객체 간 결합도 최소화 및 테스트 용이성 확보
SOLID 원칙객체지향 설계 원칙단일 책임, 개방 - 폐쇄, 리스코프 치환, 인터페이스 분리, 의존성 역전
테스트/품질보증테스트 더블Mock, Stub, Spy, Fake 등단위 테스트 및 계약 테스트 용 객체
계약 테스트Interface 기반 상호작용 검증생산자 - 소비자 간 API 계약 자동화 테스트
유지보수/리팩토링코드 리팩토링추상화 적용 및 코드 구조 개선SRP 및 DIP 원칙 기반 구조화
성능 최적화추상화 계층 최적화불필요한 계층 제거호출 오버헤드 분석 및 성능 병목 제거

용어 정리

용어설명
추상화 (Abstraction)복잡한 구현 세부사항을 감추고, 필요한 기능만 외부에 노출하는 설계 원칙
구체화 (Concretion)실제 동작을 구현한 클래스나 객체
인터페이스 (Interface)구현과 무관하게 동작의 명세만 정의하는 추상 계층
추상 클래스 (Abstract Class)일부 구현을 포함할 수 있는 추상화 계층, 상속 기반 구조에 주로 사용
계약 (Contract)인터페이스가 제공해야 하는 메서드와 그에 대한 동작 규약
DIP (Dependency Inversion Principle)고수준과 저수준 모듈 모두 추상화에 의존해야 한다는 설계 원칙
DI (Dependency Injection)객체의 의존성을 외부에서 주입하여 결합도를 낮추는 설계 기법
IoC (Inversion of Control)객체 생성과 제어 책임을 외부 (컨테이너 등) 로 위임하는 설계 원칙
팩토리 패턴 (Factory Pattern)객체 생성 책임을 팩토리 클래스로 위임해, 클라이언트가 구체 클래스에 의존하지 않도록 하는 패턴
서비스 로케이터 패턴 (Service Locator Pattern)클라이언트가 서비스의 구체 구현을 알지 않고도 접근할 수 있도록 레지스트리 역할 수행
Low Coupling (낮은 결합도)구성 요소 간 상호 의존성이 낮은 상태로, 변경 영향 최소화에 유리
High Cohesion (높은 응집도)구성 요소 내 책임이 밀접하게 연관된 상태로, 책임 명확화 및 유지보수 용이
결합도 (Coupling)모듈 간의 연결 정도를 나타내며, 낮을수록 유연한 구조
응집도 (Cohesion)모듈 내부 구성 요소들이 얼마나 관련성 있게 응집되어 있는지를 나타내는 지표
다형성 (Polymorphism)동일한 인터페이스를 통해 여러 다른 구현을 사용할 수 있는 객체지향 특성
런타임 바인딩 (Runtime Binding)실행 시점에 어떤 구체 구현이 호출될지 결정되는 메커니즘
제어 역전 (Inversion of Control)애플리케이션이 아닌 프레임워크가 객체의 흐름을 제어하는 설계 패턴
서비스 로케이터 (Service Locator)런타임에 서비스 인스턴스를 찾아 제공하는 레지스트리
테스트 더블 (Test Double)테스트 용으로 실제 객체를 대신하는 객체 (Mock, Stub, Spy, Fake 등)

참고 및 출처

원칙 및 개념

DIP 및 인터페이스 설계

아키텍처 및 프레임워크

기타 참고 블로그