티스토리 뷰

기타

SRP (Single Responsibility Principle) 원칙

developer0hye 2026. 2. 23. 09:58

요새 인수인계를 받은 프로젝트가 있다. 지금은 내 입맛대로 수정할 수 있게끔 리팩토링 작업을 주로 하는데 OCP, SRP 원칙을 지키지 않은채로 구현된 부분들을 정리중이다.

 

최대한 리팩토링 잘해서 yaml 파일 같은데에 pipeline 을 파일 레벨에서 기술해서 동작하게 하고싶다.

 

지금은 배포환경이 다른 경우 하드 코딩돼있는 부분이 많다. 이걸 코드로 하드 코딩돼있는 게 그냥 내가 관리자가 된 입장에서 싫어가지고 위와 같은 작업을 진행하고 있다.

 

SRP 원칙을 Opus4.6에게 최대한 쉽게 알려달라고 했다.


🧱 "이 클래스, 왜 이렇게 뚱뚱해?" — SRP(단일 책임 원칙) 쉽게 이해하기

코드를 짜다 보면 하나의 클래스에 이것저것 기능을 넣게 됩니다. 처음엔 편하지만, 나중에 수정할 때 지옥이 펼쳐지죠. 오늘은 이런 문제를 막아주는 **SRP(단일 책임 원칙)**에 대해 이야기해 보겠습니다.


SRP가 뭔가요?

SRP는 Single Responsibility Principle, 우리말로 단일 책임 원칙입니다.

한 줄 요약하면 이렇습니다.

"하나의 클래스는 하나의 이유로만 변경되어야 한다."

이게 무슨 말일까요? 비유로 설명해 보겠습니다.


🍳 비유: 식당의 직원

동네에 작은 식당이 하나 있다고 상상해 보세요.

사장님이 직원 한 명에게 이렇게 말합니다.

  • "너 요리도 해."
  • "너 서빙도 해."
  • "너 회계도 해."

처음엔 괜찮을 수 있습니다. 하지만 문제가 생기기 시작합니다.

  • 메뉴가 바뀌면? → 요리법을 새로 배워야 합니다.
  • 홀 배치가 바뀌면? → 서빙 동선을 새로 익혀야 합니다.
  • 세금 정책이 바뀌면? → 회계 처리를 새로 공부해야 합니다.

한 사람이 세 가지 이유로 계속 바뀌어야 하니까 실수가 생기고, 일이 느려집니다.

SRP는 이걸 이렇게 바꾸라는 겁니다.

  • 👨‍🍳 요리사 → 요리만 담당
  • 🧑‍💼 서빙 직원 → 서빙만 담당
  • 🧮 회계 담당 → 회계만 담당

각자 자기 일에만 집중하니까 한쪽이 바뀌어도 다른 쪽은 영향을 받지 않습니다.

코드도 똑같습니다.


💻 코드로 보는 SRP 위반

아래는 흔히 볼 수 있는 SRP 위반 코드입니다.

class Employee {

    // 💰 급여를 계산한다 (재무팀이 관심 있는 기능)
    public Money calculatePay() {
        // 급여 계산 로직...
    }

    // 💾 데이터베이스에 저장한다 (개발팀이 관심 있는 기능)
    public void save() {
        // DB 저장 로직...
    }

    // 📊 보고서를 만든다 (운영팀이 관심 있는 기능)
    public String generateReport() {
        // 보고서 생성 로직...
    }
}

Employee 클래스 하나가 세 가지 일을 동시에 하고 있습니다. 마치 요리도 하고, 서빙도 하고, 회계도 하는 그 직원처럼요.


💥 그래서 뭐가 문제인데요?

1. 고쳤더니 다른 데가 터진다

재무팀이 "급여 계산 방식을 바꿔주세요"라고 요청했습니다. calculatePay()를 수정했더니, 내부에서 같이 쓰던 코드 때문에 generateReport()의 숫자가 이상해졌습니다.

급여를 고쳤을 뿐인데 보고서가 깨진 겁니다. 😱

2. 코드 충돌이 잦아진다

개발팀은 save()를 고치고, 운영팀은 generateReport()를 고치고 싶습니다. 둘 다 같은 Employee.java 파일을 건드리니까 Git 충돌이 계속 납니다.

3. 테스트가 괴로워진다

급여 계산 로직 하나를 테스트하고 싶을 뿐인데, DB 연결도 준비하고 보고서 관련 설정도 해줘야 합니다. 테스트 하나 돌리려고 준비할 게 산더미입니다.

4. 재사용이 안 된다

다른 프로젝트에서 급여 계산 로직만 가져다 쓰고 싶은데, Employee 클래스를 통째로 가져와야 합니다. DB 저장 코드, 보고서 코드까지 전부 딸려옵니다.


✅ 이렇게 고치면 됩니다

책임별로 클래스를 나눠주세요.

// 💰 급여 계산만 담당
class PayCalculator {
    public Money calculatePay(Employee e) {
        // 급여 계산 로직...
    }
}

// 💾 데이터 저장만 담당
class EmployeeRepository {
    public void save(Employee e) {
        // DB 저장 로직...
    }
}

// 📊 보고서 생성만 담당
class ReportGenerator {
    public String generateReport(Employee e) {
        // 보고서 생성 로직...
    }
}

이제 각 클래스는 딱 하나의 이유로만 변경됩니다.

클래스 변경되는 이유 요청하는 사람

PayCalculator 급여 정책이 바뀔 때 재무팀
EmployeeRepository DB 구조가 바뀔 때 개발팀
ReportGenerator 보고서 양식이 바뀔 때 운영팀

서로 영향을 주지 않으니 안심하고 수정할 수 있습니다.


🔍 "혹시 내 코드도 SRP 위반?" 체크리스트

아래 항목에 해당하면 SRP 위반을 의심해 보세요.

1) 클래스를 설명할 때 "그리고"가 들어간다

"이 클래스는 주문을 처리하고, 그리고 이메일을 보내고, 그리고 로그를 남겨요."

→ 책임이 3개입니다. 분리하세요.

2) 파일이 수백 줄을 넘어간다

보통 한 클래스가 300줄을 넘으면 여러 책임이 섞여 있을 가능성이 높습니다.

3) 서로 다른 팀이 같은 파일을 자주 고친다

Git 로그를 보세요. 여러 팀이 같은 파일을 건드리고 있다면 그 파일에 여러 책임이 뒤섞여 있다는 신호입니다.

4) 테스트를 작성할 때 mock이 5개 이상 필요하다

하나의 클래스를 테스트하는데 준비물이 너무 많다면, 그 클래스가 너무 많은 일을 하고 있는 겁니다.


⚠️ 주의: 너무 쪼개지 마세요

SRP를 처음 배우면 모든 걸 잘게 쪼개고 싶은 유혹이 생깁니다.

하지만 클래스가 지나치게 많아지면 오히려 코드를 읽기 어려워집니다. 파일 50개를 열어야 하나의 흐름을 이해할 수 있다면 그것도 문제입니다.

핵심은 "지금 이 코드에서 실제로 서로 다른 이유로 변경되는 부분이 있는가?"를 따져보는 것입니다.

변경 이유가 하나뿐이라면 굳이 쪼갤 필요가 없습니다. 현실적인 균형이 중요합니다.


📝 마무리

정리하면 SRP는 이렇습니다.

  • 하나의 클래스는 하나의 책임만 가져야 한다.
  • 여기서 "책임"이란 **"변경의 이유"**를 뜻한다.
  • 위반하면 수정할 때 예상치 못한 곳이 터지고, 테스트와 협업이 어려워진다.
  • 해결 방법은 책임별로 클래스를 분리하는 것이다.
  • 단, 과도한 분리는 금물이다. 실제 변경 패턴을 보고 판단하자.

💡 코드를 작성할 때 스스로에게 물어보세요. "이 클래스가 바뀌어야 하는 이유가 몇 가지지?" 답이 2개 이상이라면, SRP 리팩토링을 고민할 때입니다.


이 글이 도움이 되셨다면 공유 부탁드립니다! 🙌

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/02   »
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
글 보관함