243. SRP (Single Responsibility Principle) - 단일 책임 원칙 SOLID 객체지향 설계 응집도 결합도 클래스 분리 유지보수성 리팩토링

핵심 인사이트: (SOLID의 첫 단추, S) 초보 개발자가 만든 '스위스 아미 나이프' 같은 Employee(직원) 만능 클래스 1개가 있다. 이 클래스 안에는 "월급 계산하기", "DB에 직원 정보 저장하기", "웹에 직원 이름 예쁘게 html로 출력하기" 함수가 다 때려 박혀있다. 사장님이 "야! 웹 화면 좀 빨간색으로 고쳐봐!"라고 해서 개발자가 html 출력 함수를 살짝 건드렸다. 그런데 나비효과로 '월급 계산' 함수가 터져서 전 직원 월급이 0원이 되는 대참사가 일어났다! 로버트 마틴이 뒷목을 잡는다. "야 이 미친놈아!! 왜 하나의 클래스(방) 안에 재무팀, DB 관리팀, 웹 디자이너 3명을 다 가둬놓고 스파게티를 끓여!! 당장 방을 3개로 찢어버려!! 하나의 클래스는 무조건 '단 하나'의 책임을 지고, 그 클래스를 뜯어고쳐야 할 이유(Reason to change)도 우주가 망해도 오직 '딱 하나'뿐이어야 해!! 그래야 화면 고치다가 월급이 털리는 개죽음을 막을 거 아니야!!" 거대 스파게티 몬스터를 칼같이 토막 내는 분업의 절대 법칙, 단일 책임 원칙(SRP)이다.

Ⅰ. 만능(God) 클래스의 비극

  • God Class: 1만 줄이 넘어가는, 혼자서 모든 일(로직, 통신, 파일 읽기, UI 화면)을 다 해 처먹는 클래스입니다.
  • 재앙: 코드가 거미줄처럼 얽혀있어(낮은 응집도), 기능 A를 수정했는데 전혀 상관없는 기능 B가 박살 나는 '사이드 이펙트(Side Effect)' 폭탄의 근원입니다. 개발자가 수정하기 두려워서 코드를 방치하게 됩니다.

Ⅱ. 단일 책임 원칙 (SRP, Single Responsibility Principle)의 개념 🌟

  • 개념: 객체지향 프로그래밍에서 **"모든 클래스, 모듈, 또는 함수는 오직 '단 하나의 책임(기능, 역할)'만을 가져야 하며, 이 클래스의 코드를 수정(변경)해야 할 이유도 오직 단 하나여야 한다"**는 아주 단순하지만 가장 지키기 어려운 설계 원칙입니다.

Ⅲ. SRP를 관통하는 핵심 척도: "변경의 이유" 🌟 핵심 기출 🌟

로버트 C. 마틴은 '책임(Responsibility)'이라는 단어를 아주 명쾌하게 재정의했습니다.

  • "책임 = 코드를 변경해야 할 이유(Reason to change)"
  • Employee 클래스의 3가지 기능 (월급 계산, DB 저장, 보고서 출력)
    1. 재무팀장이 "야! 월급 계산 방식 세금 떼는 걸로 바꿔!" ➜ (변경의 이유 1 터짐)
    2. 인프라팀장이 "야! 오라클 DB 말고 MySQL로 바꿔서 저장해!" ➜ (변경의 이유 2 터짐)
    3. 사장님이 "야! 보고서 폰트 좀 궁서체로 바꿔!" ➜ (변경의 이유 3 터짐)
  • 사형 선고: 하나의 클래스가 무려 **'3가지 완전히 다른 이유(서로 다른 액터의 요구)'**에 의해 시달리고 뜯어고쳐져야 합니다. SRP를 끔찍하게 위반한 쓰레기 코드입니다.

Ⅳ. SRP의 마법 (어떻게 찢어 발기는가?)

클래스의 배를 갈라 3명의 장인으로 완벽하게 분업(리팩토링) 시킵니다.

  1. PayCalculator 클래스: 오직 "월급 계산" 로직(핵심 비즈니스)만 죽어라 팝니다. 재무팀장이 딴지 걸 때만 이 코드가 바뀝니다.
  2. EmployeeRepository 클래스: 오직 "DB 쿼리"만 날립니다. DB를 교체할 때 이 파일만 딱 고치면 끝납니다.
  3. ReportFormatter 클래스: 오직 "글씨 예쁘게 꾸미기"만 합니다. 사장님이 폰트를 바꿔달라면 아무 눈치 안 보고 얘만 살짝 고치면 끝납니다.
  • 결과 (응집도의 극대화): 각 클래스가 자기 본업에만 미치도록 충실해지면서(High Cohesion), 남의 코드를 건드리지 않아 결합도는 바닥을 찍고(Low Coupling), 수정 시 버그 발생 확률이 0%로 수렴합니다.

📢 섹션 요약 비유: **단일 책임 원칙(SRP)**은 맥가이버칼을 버리고 **'전문 장인의 도구함'**을 짜는 과정입니다. 멍청한 목수는 칼, 톱, 드라이버, 가위가 하나로 뭉쳐있는 '뚱뚱한 맥가이버칼 만능 도구(God Class)' 하나로 집을 지으려 합니다. 톱질을 하려는데 옆에 튀어나온 가위 날에 손을 베이고, 드라이버가 고장 나면 수리를 위해 맥가이버칼 통째로 공장에 맡겨야 해서 아무 작업도 못 하는 재앙(수정의 부작용)이 터집니다. SRP의 대원칙은 뚱뚱한 맥가이버칼의 부품들을 다 해체해서, **"오직 나무만 자르는 전용 톱(클래스 1)", "오직 나사만 돌리는 전용 십자드라이버(클래스 2)"**로 완벽하게 개별 도구로 쪼개어 도구함에 예쁘게 진열하는 것입니다. 이렇게 찢어놓으면 나사가 헛돌 때 드라이버만 쓱 빼서 1초 만에 수리(코드 변경)하면 되고, 그 과정에서 톱이나 칼이 망가질(나비효과 버그) 확률은 아예 물리학적으로 0%가 됩니다. 하나의 도구(클래스)는 오직 자기가 맡은 하나의 일(책임)에만 미치도록 집중하게 만들어, 유지보수와 고장 수리를 세상에서 가장 평화롭게 만들어주는 객체지향 1계명입니다.