생각해 보자 님의 블로그

프로그래밍에서 단일 책임 원칙 이란? 무엇을 고려해야 할까? 본문

테크 지식

프로그래밍에서 단일 책임 원칙 이란? 무엇을 고려해야 할까?

woohyuntak 2025. 3. 13. 23:18

1. 배경

현재 진행하는 프로젝트에서 글로벌 에러 핸들링을 담당하는 파일이 있었습니다. 그러나 프로젝트 구조상 서비스 레이어에서 레포지토리에서 넘어온 값을 하나하나 조건문을 통해 검사를 진행하는 방식이었습니다.

이러한 구조에서는 모듈이 많아질수록 함수들이 증가하게 되고, 개발 생산성에도 영향을 미칠 뿐만 아니라 추후 테스트 코드를 작성할 때 커버리지에도 영향을 줄 가능성이 있었습니다. 이를 해결하기 위해 글로벌 에러 핸들링 파일에 각 라이브러리(multer, Prisma 등)에서 발생하는 에러 타입을 확인하고 추가하는 방식을 선택했습니다.

기능은 정상적으로 작동했지만, 하나의 파일에서 너무 많은 조건을 관리하게 되면서 가독성과 유지보수성이 떨어질 우려가 있었습니다. 자료를 조사하던 중 "단일 책임 원칙(Single Responsibility Principle, SRP)"이라는 개념을 알게 되었고, 이를 적용하면 어떻게 개선할 수 있을지 고민하게 되었습니다.

이번 글에서는 프로그래밍에서의 단일 책임 원칙에 대해 알아보고, 적용할 때 고려해야 할 점을 함께 고민해 보겠습니다.

2. 고민

하나의 파일에서 너무 많은 역할을 수행하다 보니, 다음과 같은 문제점들이 나타났습니다:

  • 코드의 가독성 저하: 다양한 에러 처리를 한 파일에서 관리하다 보니, 코드가 길어지고 복잡해졌습니다.
  • 유지보수 어려움: 특정 라이브러리(multer, Prisma)의 예외 처리를 수정하려면, 기존의 글로벌 필터를 수정해야 했습니다.
  • 확장성 부족: 새로운 에러 유형이 추가될 경우, 기존의 필터에 계속해서 조건문을 추가해야 하는 문제가 있었습니다.

이러한 문제를 해결하기 위해 자료를 조사하던 중 "단일 책임 원칙(SRP)"을 알게 되었습니다.

3. 단일 책임 원칙이란?

단일 책임 원칙(SRP)이란 **"하나의 클래스(혹은 모듈)는 오직 하나의 변경 이유만을 가져야 한다"**는 개념입니다. 즉, 하나의 파일이나 함수가 여러 역할을 수행하는 것이 아니라, 특정한 기능을 중심으로 역할을 나누어야 합니다.

이 원칙을 글로벌 필터에 적용한다면, 다음과 같이 개선할 수 있습니다:

  1. 에러 유형별 핸들러 분리: multer, Prisma, 그리고 기타 일반적인 HTTP 예외를 각각 별도의 파일로 분리합니다.
  2. 에러 핸들링을 개별 클래스로 관리: 각 핸들러에서 특정 라이브러리의 에러만을 처리하도록 구성합니다.
  3. 중앙 글로벌 필터에서 통합: 개별 핸들러를 글로벌 필터에서 호출하는 방식으로 변경합니다.

4. 고려해야 할 점

단일 책임 원칙을 적용할 때 고려해야 할 사항은 다음과 같습니다:

  • 적절한 책임 분리: 너무 세분화하면 오히려 관리가 어려울 수 있으므로, 적절한 수준에서 역할을 나누는 것이 중요합니다.
  • 확장성을 고려한 설계: 새로운 예외 유형이 추가되더라도 기존의 구조를 크게 변경하지 않고 쉽게 확장할 수 있도록 설계해야 합니다.
  • NestJS의 DI(의존성 주입) 활용: 개별 핸들러를 NestJS의 프로바이더로 등록하여 효율적으로 관리할 수 있습니다.

5. 결론

기존의 글로벌 필터에서 모든 예외를 처리하는 방식은 유지보수성과 가독성 측면에서 한계를 가질 수 있습니다. 단일 책임 원칙을 적용하여 예외 처리 로직을 개별 핸들러로 분리하면, 코드의 가독성을 높이고 유지보수를 용이하게 만들 수 있습니다.

이러한 개선을 통해 프로젝트의 코드 품질을 높이고, 개발 과정에서 예외 처리를 더욱 효과적으로 관리할 수 있을 것입니다.