Single Responsibility Principle

Single Responsibility Principle(단일 책임 원칙, SRP) 은 SOLID 설계 원칙 중 하나로, " 클래스, 모듈, 함수 등은 오직 하나의 책임만을 가져야 하며, 단 하나의 변경 이유만을 가져야 한다 " 는 원칙이다. SRP 를 적용하면 각 클래스가 명확한 역할을 갖고, 코드의 응집도가 높아지며, 유지보수성과 테스트 용이성이 크게 향상된다. SRP 는 대규모 시스템, 마이크로서비스, 도메인 주도 설계 등 다양한 환경에서 핵심적으로 적용된다.

핵심 개념

정의 및 기본 개념

핵심 원리

  1. 분리의 원칙: 서로 다른 이유로 변경되는 기능들을 분리
  2. 단일 목적: 각 구성요소는 명확하고 단일한 목적을 가져야 함
  3. 변경 격리: 한 기능의 변경이 다른 기능에 영향을 주지 않아야 함
graph TD
    A[단일 책임 원칙] --> B[하나의 책임]
    A --> C[하나의 변경 이유]
    A --> D[하나의 Actor]
    
    B --> E[명확한 목적]
    B --> F[기능적 응집성]
    
    C --> G[변경 격리]
    C --> H[영향 범위 최소화]
    
    D --> I[이해관계자 분리]
    D --> J[요구사항 분할]

배경 및 필요성

발전 배경

목적 및 필요성

  1. 코드 복잡성 감소: 각 구성요소의 역할을 명확히 하여 이해하기 쉬운 코드 작성
  2. 유지보수성 향상: 변경 사항의 영향 범위를 제한하여 안전한 수정 가능
  3. 재사용성 증대: 단일 목적의 구성요소는 다른 컨텍스트에서 재사용 용이
  4. 테스트 용이성: 각 구성요소를 독립적으로 테스트 가능
  5. 병렬 개발: 서로 다른 팀이 독립적으로 개발 가능

주요 기능 및 역할

설계 차원의 역할

개발 차원의 역할

특징

설계적 특징

구현적 특징

핵심 원칙

SRP 는 모듈이 하나의 책임만을 가지도록 설계하여, 변경의 이유를 하나로 제한한다. 이를 통해 코드의 응집도를 높이고, 변경에 따른 영향을 최소화한다.

기본 원칙

  1. 단일 책임: 클래스는 오직 하나의 책임만을 가져야 함
  2. 단일 변경 이유: 클래스가 변경되는 이유는 오직 하나여야 함
  3. 단일 Actor: 클래스는 하나의 이해관계자 그룹에만 책임을 져야 함

적용 원칙

flowchart TD
    A[요구사항 분석] --> B{여러 책임 존재?}
    B -->|Yes| C[책임 분리]
    B -->|No| D[단일 책임 유지]
    
    C --> E[별도 클래스 생성]
    E --> F[인터페이스 정의]
    F --> G[의존성 주입]
    
    D --> H[구현 완료]
    G --> H

작동 원리

식별 과정

  1. 책임 식별: 클래스나 모듈이 수행하는 모든 기능 나열
  2. 변경 이유 분석: 각 기능이 변경될 수 있는 이유 파악
  3. Actor 구분: 변경을 요구하는 이해관계자 그룹 식별
  4. 분리 결정: 서로 다른 이유로 변경되는 기능들을 별도 모듈로 분리

리팩토링 과정

sequenceDiagram
    participant Dev as 개발자
    participant Code as 기존 코드
    participant Analysis as 분석
    participant Refactor as 리팩토링

    Dev->>Code: 다중 책임 클래스 식별
    Code->>Analysis: 책임 분석
    Analysis->>Analysis: 변경 이유 파악
    Analysis->>Refactor: Extract Class 적용
    Refactor->>Refactor: 인터페이스 정의
    Refactor->>Dev: 단일 책임 클래스들

아키텍처 다이어그램

classDiagram
    class UserController {
        +createUser(request)
        +updateUser(id, request)
        +deleteUser(id)
    }
    
    class UserService {
        +createUser(userData)
        +updateUser(id, userData)
        +deleteUser(id)
    }
    
    class UserRepository {
        +save(user)
        +findById(id)
        +delete(id)
    }
    
    class UserValidator {
        +validateUserData(userData)
        +validateEmail(email)
    }
    
    class EmailService {
        +sendWelcomeEmail(user)
        +sendNotification(user, message)
    }
    
    UserController --> UserService : uses
    UserService --> UserRepository : uses
    UserService --> UserValidator : uses
    UserService --> EmailService : uses
구분항목기능역할특징
설계 원칙책임 경계 (Responsibility Boundary)클래스나 모듈의 책임 범위 정의책임 있는 부분과 없는 부분을 명확히 구분이해하기 쉬운 경계 설정
구성 요소인터페이스 (Interface)구성요소 간 상호작용 방식 정의구현 세부사항은 숨기고 계약만 제공변경에 강하고 안정적인 설계
구현 요소구현체 (Implementation)실제 비즈니스 로직 수행구체 기능 제공 및 단일 책임 집중테스트 가능하고 유연한 변경 구조
설계 기법의존성 주입 컨테이너 (DI Container)의존성 관리 자동화런타임에 적절한 구현체 주입느슨한 결합 및 구성 유연성 확보
디자인 패턴팩토리 패턴 (Factory Pattern)객체 생성 로직 캡슐화생성 책임을 클라이언트로부터 분리생성과 사용의 명확한 분리

구현 기법

구현 기법정의/구성목적/예시
역할별 클래스 분리각 책임별로 클래스를 분리서비스/저장소 분리, 컨트롤러/비즈니스 로직 분리 등
인터페이스/추상 클래스 활용공통 기능 추상화, 구현체 분리저장소 인터페이스, 출력 인터페이스 등
유틸리티 클래스 분리공통 기능을 별도 유틸리티 클래스로 분리날짜 처리, 포맷 변환 등

Extract Class 기법

 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
27
28
29
30
31
32
33
34
// 기존 - SRP 위반
class UserManager {
    public void createUser(String name, String email) {
        // 사용자 생성 로직
        User user = new User(name, email);
        database.save(user);
        
        // 이메일 발송 로직 (다른 책임)
        Email email = new Email();
        email.setTo(user.getEmail());
        email.setSubject("환영합니다!");
        emailSender.send(email);
    }
}

// 개선 - SRP 적용
class UserService {
    private EmailService emailService;
    
    public void createUser(String name, String email) {
        User user = new User(name, email);
        database.save(user);
        emailService.sendWelcomeEmail(user);
    }
}

class EmailService {
    public void sendWelcomeEmail(User user) {
        Email email = new Email();
        email.setTo(user.getEmail());
        email.setSubject("환영합니다!");
        emailSender.send(email);
    }
}

Extract Method 기법

Interface Segregation 기법

Dependency Injection 기법

장점과 단점

구분항목설명
✅ 장점코드 가독성 향상각 클래스의 목적이 명확하여 이해하기 쉬움
유지보수성 개선변경 사항의 영향 범위가 제한되어 안전한 수정 가능
테스트 용이성단일 책임으로 인해 독립적인 테스트 작성 가능
재사용성 증대명확한 목적의 구성요소는 다른 컨텍스트에서 재사용 용이
병렬 개발 지원서로 다른 팀이 독립적으로 개발 가능
⚠ 단점복잡성 증가동일한 기능을 위해 더 많은 클래스 필요
과도한 추상화불필요한 추상화로 인한 코드 복잡성 증가
책임 정의의 어려움적절한 책임 범위 결정의 주관성
성능 오버헤드구성요소 간 통신으로 인한 성능 저하 가능성
초기 개발 비용설계 단계에서 더 많은 시간과 노력 필요

단점 해결 방법

과도한 분할 방지

성능 최적화

명확한 가이드라인 수립

도전 과제

도전 과제설명해결책
책임 정의의 모호성무엇이 단일 책임인지 정의하기 어려움도메인 전문가와 협업, 변경 빈도 기준으로 책임 범위 정의
역할 분리 기준의 불명확성역할의 경계가 불분명하면 설계가 복잡해짐도메인 분석 기반 역할 정의, 코드 리뷰 강화
과도한 역할 분할분할이 지나치면 관리할 클래스와 모듈이 지나치게 많아짐실용적 관점에서 점진적 리팩토링 적용
클래스/파일 수 증가분리로 인해 클래스 및 파일 수가 급증패키지 구조 체계화, 네이밍 규칙 준수
중복 코드 발생 위험동일한 기능을 여러 구현체에서 반복할 가능성공통 기능을 유틸리티 클래스로 추출 및 재사용
레거시 시스템 적용의 어려움기존 시스템에 원칙 적용 시 리팩토링 비용과 리스크가 큼Strangler Fig 패턴을 활용한 점진적 전환
팀 간 커뮤니케이션 오버헤드모듈 분리로 인한 팀 간 협업 복잡성명확한 인터페이스 정의, 설계 문서화 및 아키텍처 가이드 공유

분류 기준에 따른 종류 및 유형

분류 기준유형설명예시
적용 레벨클래스 레벨개별 클래스의 단일 책임UserService, EmailService
모듈 레벨패키지/모듈의 단일 책임인증 모듈, 결제 모듈
서비스 레벨마이크로서비스의 단일 책임사용자 서비스, 주문 서비스
책임 유형데이터 처리데이터 변환, 검증, 포맷팅DataValidator, DataFormatter
비즈니스 로직핵심 업무 규칙 처리OrderCalculator, InventoryManager
외부 연동외부 시스템과의 통신PaymentGateway, EmailSender
인프라 관리기술적 관심사 처리DatabaseConnection, Logger
분리 전략수직 분리계층별 책임 분리Controller, Service, Repository
수평 분리기능별 책임 분리UserManager, ProductManager
시간적 분리생명주기별 책임 분리Factory, Destroyer

실무 적용 예시

영역적용 사례분리 전 구조분리 후 구조기대 효과
웹 개발MVC 패턴모든 로직이 하나의 클래스Controller, Service, Repository 계층 분리계층별 책임 명확화, 유지보수 용이
데이터 처리ETL 파이프라인 분리추출·변환·적재 통합 처리Extractor, Transformer, Loader 모듈 분리각 단계별 독립적 개발 및 테스트 가능
인증 시스템인증/인가/세션 분리인증 기능 통합AuthService, AuthorizationService, SessionService보안 책임 분리, 기능별 테스트 용이
결제 시스템결제 프로세스 분리검증·처리·알림 통합PaymentValidator, PaymentProcessor, NotificationService단계별 안정성 확보 및 기능 확장 용이
로깅 시스템로그 수집/처리/저장 책임 분리로그 기능이 하나의 클래스에 집중LogCollector, LogFormatter, LogStorage성능 최적화 및 포맷 다양성 대응 가능
사용자 관리 시스템사용자 정보 관리 vs 인증 분리단일 모듈에 모든 사용자 기능 포함UserProfileService, AuthenticationService책임 명확화, 보안 기능 독립화
백엔드 서비스비즈니스 로직과 저장소 책임 분리단일 서비스 클래스Service, Repository 인터페이스 및 구현 분리DIP 적용으로 테스트 용이성 증가
프론트엔드 컴포넌트역할별 UI 분리UI 처리 통합ViewComponent, EventHandlerComponent 등 역할 기반 분리재사용성 향상, 유지보수 용이
유틸리티 관리공통 기능 유틸 클래스 분리기능 중복 존재DateUtil, FormatUtil 등 독립 클래스 구성중복 제거, 코드 일관성 확보

활용 사례

사례 1: 전자상거래 주문 시스템

시나리오: 온라인 쇼핑몰의 주문 처리 시스템을 SRP 를 적용하여 설계하는 사례

시스템 구성:

graph TB
    A[OrderController] --> B[OrderService]
    B --> C[PaymentService]
    B --> D[InventoryService]
    B --> E[ShippingService]
    B --> F[NotificationService]
    
    C --> G[PaymentGateway]
    D --> H[InventoryRepository]
    E --> I[ShippingProvider]
    F --> J[EmailService]
    F --> K[SMSService]
    
    H --> L[(Database)]
    G --> M[외부 결제 API]
    I --> N[배송업체 API]

각 구성요소의 단일 책임:

Workflow:

sequenceDiagram
    participant Client
    participant OrderController
    participant OrderService
    participant PaymentService
    participant InventoryService
    participant ShippingService
    participant NotificationService

    Client->>OrderController: 주문 요청
    OrderController->>OrderService: 주문 처리 요청
    OrderService->>InventoryService: 재고 확인
    InventoryService-->>OrderService: 재고 상태
    OrderService->>PaymentService: 결제 처리
    PaymentService-->>OrderService: 결제 결과
    OrderService->>ShippingService: 배송 요청
    ShippingService-->>OrderService: 배송 정보
    OrderService->>NotificationService: 알림 발송
    NotificationService-->>OrderService: 발송 완료
    OrderService-->>OrderController: 처리 결과
    OrderController-->>Client: 응답

SRP 적용 효과:

사례 2: 온라인 학습 플랫폼

시나리오: 온라인 학습 플랫폼

시스템 구성:

시스템 아키텍처 다이어그램

classDiagram
  class CourseCreator {
    +createCourse()
  }

  class CourseEditor {
    +editCourse()
  }

  class CourseDeleter {
    +deleteCourse()
  }

  class Frontend {
    +handleUserInput()
  }

  Frontend --> CourseCreator
  Frontend --> CourseEditor
  Frontend --> CourseDeleter

Workflow:

  1. 사용자가 강좌 생성 요청
  2. CourseCreator 가 요청 처리
  3. 강좌 편집 요청 시 CourseEditor 가 처리
  4. 삭제 요청은 CourseDeleter 가 처리

역할 분리 효과:

실무 적용 고려사항 및 권장사항

구분고려사항설명권장사항
설계 단계책임 정의 명확화모듈 또는 클래스의 역할을 혼동하지 않도록 함도메인 전문가와 협업하여 명확한 책임 경계 설정
변경 빈도 분석자주 바뀌는 기능을 기준으로 책임을 분리과거 변경 이력 분석, 요구사항 중심 설계
적절한 추상화 수준과도한 추상화는 유지보수를 어렵게 할 수 있음기능 중심의 실용적 추상화 적용
구현 단계인터페이스 우선 설계구현체보다 추상화 중심의 구조를 먼저 정의함인터페이스 기반 의존성 설계로 DIP 준수
점진적 리팩토링초기 도입 시 전체 재설계보다 점진적 적용이 효과적기능 단위로 단계적 구조 개선
테스트 주도 개발 (TDD)구조적 책임 분리를 테스트와 병행할 수 있음단위 테스트 기반 개발로 자연스럽게 SRP 유도
운영 단계코드/파일 증가역할 분리로 인해 클래스 및 파일 수 증가 가능성패키지 구조 체계화, 네이밍 표준화, 문서화
코드 중복공통 로직이 여러 모듈에 반복될 가능성유틸리티 클래스 또는 공통 인터페이스 추출
모듈 간 결합도모듈 간 강한 의존은 유지보수 비용을 높임인터페이스/DI 활용하여 결합도 최소화
지속적 모니터링리팩토링 시점이나 책임 범위 재조정 타이밍 판단 필요변경 빈도, 코드 복잡도 등의 지표 기반으로 개선 계획 수립
팀 협업팀 내 일관성 확보SRP/DIP 등 원칙 적용에 대한 이해도 차이 발생 가능성정기적 교육, 코드 리뷰 기준 설정, 아키텍처 가이드 공유

최적화 고려사항 및 주의할 점

구분고려사항설명권장사항
성능 최적화구성요소 간 통신 비용모듈 간 과도한 호출로 인한 오버헤드 발생 가능인터페이스 통한 일괄 처리, 캐싱 전략 적용
메모리 사용량객체 과다 생성 시 GC(Garbage Collection) 부담 증가객체 풀링 (Pooling), 싱글톤 (Singleton) 등으로 관리
네트워크 호출 최적화마이크로서비스, 분산 환경에서 네트워크 비용 발생배치 호출, GraphQL, API Gateway 활용 등으로 호출 최소화
구조 최적화의존성 그래프 관리순환 의존 발생 시 구조 불안정의존성 방향 명확화, 계층 아키텍처 또는 헥사고날 아키텍처 적용
인터페이스 안정성자주 바뀌는 인터페이스는 의존 모듈에 영향을 줌도메인 안정성 기준으로 인터페이스 설계, 의사결정 기록 (ADR) 문서화
모듈 경계 최적화과도한 모듈화 시 복잡도 증가도메인/기능 기준으로 합리적 분할, 역할/경계 명확화
개발 최적화코드 중복책임 분리 중 반복 로직 발생 가능공통 기능을 유틸리티 또는 공유 서비스로 모듈화
개발 생산성과도한 보일러플레이트 (boilerplate) 로 개발 속도 저하DI 프레임워크 (Spring, NestJS 등) 적극 활용, 코드 생성 도구 사용
문서화 자동화구조가 복잡해질수록 문서 미비로 협업 어려움README, ADR 문서, Swagger, Typedoc 등 자동 문서화 도구 활용
설계 최적화역할 정의/경계 불분명SRP(단일 책임 원칙) 적용 시 경계 설정이 모호할 수 있음도메인 분석 기반 역할 정의, 표준화 및 코드 리뷰 강화
변경 용이성요구사항 변화 시 유연하게 대처 가능한 구조 필요OCP(개방 - 폐쇄 원칙), SRP 원칙 기반 설계 적용
테스트 용이성모듈 간 결합도가 높으면 테스트 어려움의존성 주입 (DI) 기반 테스트 구조 구성, 단위 테스트 우선 설계
운영/협업 최적화모듈 경량화지나친 분할로 인한 유지보수 및 배포 복잡성 증가기능 단위로 경량화, 디렉토리 구조 명확화
모듈 재사용성비슷한 책임의 모듈을 반복 개발하게 될 수 있음일반화된 인터페이스 설계 및 공유 모듈화
의사소통 명확성구조가 복잡할수록 팀원 간 책임/경계 혼란 발생 가능책임 및 경계 문서화, 정기적인 아키텍처 공유 및 리뷰

SRP 관련 주요 문제와 해결 방안

문제 유형원인영향탐지/진단 방법예방 방안해결 전략
책임 모호화책임 정의가 불분명하거나 도메인 분석 부족변경 충돌, 설계 오해, 테스트 난이도 상승설계 리뷰, 변경 이력 분석, 코드 리뷰도메인 전문가 협업, 명세 기반 책임 문서화책임 재정의, 역할 분할, 클래스 분리
과도한 역할 분리모든 기능을 억지로 분리하려는 잘못된 SRP 해석클래스/파일 수 증가, 보일러플레이트 증가, 설계 복잡도 증가클래스 수 증가 모니터링, 정적 분석 툴 (Coupling/Complexity)실용적 SRP 해석 적용 (비즈니스/변경 단위 기준)일부 모듈 통합, 리팩토링
God Class여러 책임이 한 클래스에 집중되어 있음높은 결합도, 낮은 응집도, 테스트/유지보수 복잡성클래스 크기 (라인/메서드 수), 의존성 수, 복잡도 메트릭 (Cyclomatic)정기적 코드 리뷰, 모듈 응집도 평가Extract Class, Extract Method 리팩토링
Shotgun Surgery단일 책임이 제대로 분리되지 않아 다양한 곳에서 동시에 변경 발생유지보수 리스크 증가, 생산성 저하변경 이력 분석 (버전 관리 시스템), 변경 빈도 추적연관 기능은 하나의 클래스/모듈로 집중Move Method, Move Field 리팩토링
Feature Envy기능이 다른 클래스의 데이터에 과도하게 의존캡슐화 위반, 불필요한 결합도 증가메소드 호출 패턴 분석, 정적 분석 도구 사용데이터와 책임의 일치 유지, 정보 은닉 원칙 준수Move Method 를 통해 기능 이동
Large Class장기간 책임이 누적되어 클래스가 비대화됨테스트 어려움, 변경 충돌 위험 증가클래스 라인/필드/메소드 수 분석, 응집도 (Cohesion) 분석관심사 분리 기반 설계, 기능별 구조 정의Extract Class, Extract Subclass 패턴
Divergent Change클래스가 다양한 이유로 자주 변경됨예측 불가한 변경 전파, 유지보수 난이도 증가변경 이력 분석, 이유별 변경 빈도 분류변경 이유 기준 책임 분리 (기능/도메인 중심)Extract Class 로 변경 이유별 클래스 분리
Middle Man지나치게 위임만 하는 클래스가 생김 (SRP 적용의 부작용)성능 오버헤드, 코드 복잡성, 설계 이해도 저하위임만 하는 클래스 탐지, 로직 비율 분석위임 필요성 명확히 판단 후 설계 결정Remove Middle Man 리팩토링
모듈 간 의존성 증가책임 분리 이후 모듈 간 공유 데이터/행동 증가결합도 증가, 변화 전파 위험성DI 사용 로그, 영향도 분석 도구이벤트 기반 아키텍처, 안정적 인터페이스 정의Pub/Sub, 메시지 큐, 인터페이스 개선 등으로 통신 구조 재설계
코드 중복 발생유사한 책임을 분산하면서 공통 기능이 중복됨중복 로직, 유지보수 비용 증가, 버그 유발 가능성중복 탐지 도구 (e.g., SonarQube), 코드 리뷰공통 로직 유틸리티화, 인터페이스 기반 공통 책임 관리Extract Utility Class, Template 패턴 등 재사용 구조 설계

주제와 관련하여 주목할 내용

주제항목설명
설계 원칙SRP (단일 책임 원칙)클래스/모듈은 하나의 책임만 가져야 하며, 변경 이유도 하나여야 함
OCP (개방/폐쇄 원칙)확장에는 열려 있고, 기존 코드는 수정하지 않아야 함
LSP (리스코프 치환 원칙)하위 타입은 상위 타입을 완전히 대체할 수 있어야 함
ISP (인터페이스 분리 원칙)클라이언트는 사용하지 않는 인터페이스에 의존하지 않아야 함
DIP (의존성 역전 원칙)고수준, 저수준 모듈 모두 추상화에 의존해야 하며 구체 구현에 의존하면 안 됨
설계 패턴Strategy Pattern알고리즘을 캡슐화하여 런타임에 동적으로 교체 가능
Command Pattern요청을 객체로 캡슐화하여 요청 매개변수화 및 실행 큐 지원
Observer Pattern상태 변화가 발생하면 관련 객체 (구독자) 에게 자동 통보
Factory Pattern객체 생성을 전담하는 클래스를 통해 생성 책임과 사용 책임을 분리
코드 품질Code Smell유지보수에 불리한 구조나 설계상의 문제점을 암시하는 코드 패턴
Refactoring기능은 동일하게 유지하면서 코드 구조를 개선하는 작업
Clean Code읽기 쉽고, 예측 가능하며, 변경에 강한 고품질 코드 작성 원칙
Technical Debt빠른 개발을 위해 축적된 구조적 부채, 장기적으로 유지보수 비용 증가 원인
아키텍처Microservices단일 책임 원칙에 기반한 작고 독립적인 서비스 간 통신 구조
Domain-Driven Design (DDD)도메인 모델을 기반으로 책임과 경계를 명확히 나누는 설계 전략
Hexagonal Architecture내부 비즈니스 로직과 외부 시스템 (데이터베이스, UI 등) 의 의존성을 명확히 분리
Clean Architecture의존성 규칙을 적용하여 계층별로 책임과 변경 가능성을 통제
실무 적용책임 분리 기반 계층 구조예: Controller / Service / Repository 로 계층 분리
유틸리티 및 공통 모듈 분리공통 기능을 분리해 재사용성 증대 및 코드 중복 최소화
테스트 가능 구조SRP + DIP 기반으로 Mocking 이 쉬운 구조 설계로 테스트 용이성 확보

심화학습 및 연계 주제

카테고리주제/패턴 또는 기법설명
설계 원칙OCP (개방/폐쇄 원칙)SRP 기반 구조는 OCP 적용의 기초가 되며, 변경 없이 기능 확장 가능
ISP (인터페이스 분리 원칙)책임 단위에 맞춘 인터페이스 설계를 통해 SRP 와 시너지 생성
Law of Demeter (데메테르 법칙)낮은 결합도 유지를 위한 최소 지식 원칙, SRP 기반 설계에 부합
DRY / YAGNI중복 제거와 불필요한 책임 방지를 통해 SRP 보조
리팩토링 기법Extract Class / Method책임 분리를 위한 대표적 기법, 하나의 클래스가 두 개 이상의 책임을 질 경우 유용
Move Method / Move Field책임에 따라 메소드나 필드를 적절한 클래스로 이동하여 응집도 개선
Replace Conditional with Polymorphism역할에 따라 조건문을 다형성으로 대체하여 단일 책임 구현
Introduce Parameter Object연관된 매개변수들을 묶어 책임 단위 객체로 추출
테스트 전략Unit Testing / Mock ObjectsSRP 구조에서는 단위 테스트가 단순하며 모의 객체 사용 용이
Test-Driven Development (TDD)SRP 에 적합한 설계를 자연스럽게 유도
Behavior-Driven Development (BDD)행위 중심 테스트를 통해 책임 명확화
아키텍처 및 시스템Microservices Architecture서비스 단위로 SRP 적용, 각 서비스는 독립된 단일 책임 수행
Layered ArchitectureController, Service, Repository 계층 간 책임 분리 적용
Hexagonal Architecture / Clean Architecture내부 도메인 로직과 외부 의존성 분리를 통해 SRP 구조화
Event-Driven Architecture모듈 간 강한 결합을 제거하고 이벤트 단위로 책임 분리
CQRS / Event Sourcing읽기/쓰기 또는 상태 변경을 별도 책임으로 분리
도메인 설계DDD (Domain-Driven Design)Bounded Context 기반으로 책임 단위 도출
Repository Pattern / Unit of Work데이터 액세스 책임을 별도 계층으로 분리하여 SRP 적용
함수형 프로그래밍Pure Function / Immutability부작용 없는 함수와 불변성을 활용해 단일 책임 함수 설계
Function Composition작은 책임 함수 조합으로 복잡한 로직 구성
문서화 및 관리ADR (Architecture Decision Record)책임 분리 기준과 설계 이유를 기록
README / UML / 설계 리뷰SRP 적용 결과 및 책임 단위 명세 공유
DevOps/자동화Infrastructure as Code / CI-CD Pipeline빌드, 테스트, 배포 단계를 모듈별로 책임 분리
Container Orchestration (K8s 등)컨테이너 단위로 책임 단일화, 독립 배포 가능 구조 설계

용어 정리

핵심 개념

용어설명
Cohesion (응집도)클래스나 모듈이 하나의 목적을 위해 얼마나 밀접하게 관련되어 있는지를 나타내는 정도
Coupling (결합도)모듈 간 상호 의존성의 정도. 낮을수록 변경에 강하고 유지보수가 쉬움
Actor (액터)변경을 요구하는 이해관계자나 시스템 외부 주체
Code Smell코드에서 더 깊은 문제를 암시하는 구조적 결함의 징후
Utility Class공통 기능 (날짜 처리, 문자열 포맷 등) 을 제공하는 재사용 가능한 클래스
Domain Analysis시스템의 요구사항을 분석하고 역할 및 책임을 식별하는 과정

객체지향 설계 원칙

용어설명
SRP (Single Responsibility Principle)클래스나 모듈은 하나의 책임만을 가져야 한다는 설계 원칙
SOLID객체지향 설계 5 대 원칙의 집합: SRP, OCP, LSP, ISP, DIP
OCP (Open-Closed Principle)확장에는 열려 있고, 수정에는 닫혀 있어야 한다는 원칙
LSP (Liskov Substitution Principle)하위 타입은 상위 타입을 대체할 수 있어야 한다는 원칙
ISP (Interface Segregation Principle)클라이언트는 사용하지 않는 인터페이스에 의존하지 않아야 한다는 원칙
DIP (Dependency Inversion Principle)상위 모듈과 하위 모듈은 구체화가 아닌 추상화에 의존해야 한다는 원칙

설계 및 구현 기법

용어설명
Interface (인터페이스)객체 간 상호작용의 계약을 정의하는 추상화 계층
Dependency Injection (DI)객체의 의존성을 외부에서 주입받아 결합도를 낮추는 기법
Modularization (모듈화)책임 단위별로 코드를 분리해 독립성과 재사용성을 높이는 구조화 전략
Refactoring (리팩토링)코드의 외부 동작을 유지하면서 내부 구조를 개선하는 과정
UML (Unified Modeling Language)시스템 설계를 시각화하기 위한 표준화된 다이어그램 언어
ADR (Architecture Decision Record)아키텍처 및 설계 결정 사항을 문서화해 추적 가능하게 하는 형식화된 기록

디자인 패턴

용어설명
Strategy Pattern알고리즘을 캡슐화하여 동적으로 교체할 수 있도록 설계하는 패턴
Command Pattern요청을 객체로 캡슐화하여 실행, 큐잉, 로그 등의 기능을 유연하게 처리하도록 하는 패턴
Observer Pattern객체의 상태 변화가 있을 때 등록된 관찰자에게 자동으로 통지하는 패턴
Factory Pattern객체 생성 로직을 분리하여 객체 생성을 캡슐화하고 확장에 유리하게 만드는 패턴
Chain of Responsibility요청을 여러 처리 객체 중 하나가 처리할 수 있도록 연결한 패턴

아키텍처 및 구조

용어설명
Microservices애플리케이션을 독립적으로 배포 가능한 작은 서비스 단위로 분리한 아키텍처
Hexagonal Architecture애플리케이션 핵심 도메인을 외부 의존성과 분리하고, 포트/어댑터 구조를 따르는 아키텍처 패턴
Clean Architecture의존성 규칙을 기반으로 계층 간 분리를 엄격히 지켜 유연성과 테스트 용이성을 확보하는 아키텍처
Domain Driven Design (DDD)도메인 모델을 중심으로 문제를 설계하고 구현하는 방법론

테스트 및 개발 방법론

용어설명
Unit Test (단위 테스트)클래스 또는 함수 같은 작은 단위의 로직을 독립적으로 검증하는 테스트 방식
Test-Driven Development (TDD)테스트를 먼저 작성하고 구현하는 테스트 주도 개발 방법론
Behavior-Driven Development (BDD)사용자 행위 중심으로 테스트 케이스를 작성하고 검증하는 개발 방식
Mock Object (모의 객체)테스트에서 실제 객체를 대체하기 위해 사용하는 테스트 더블 객체

참고 및 출처