Samsung Tech Blog - 코드 없이 이해하는 '단일책임원칙(SRP)' 이야기
Samsung Tech Blog - 코드 없이 이해하는 '단일책임원칙(SRP)' 이야기
SW 설계의 핵심인 '단일책임원칙'을 어려운 코드 대신 인체 장기와 일상 사물의 비유로 쉽게 풀어낸 가이드입니다. 책임과 기능의 명확한 구분부터 설계의 트레이드오프까지, 복잡한 공학 원리
techblog.samsung.com
단일책임원칙 (Single Responsibility Principle, SRP)
보통 SRP를 설명할 때는 클래스 다이어그램을 그리거나, 비대한 클래스를 쪼개는 방식으로 이야기를 하지만
이번 블로그에 코드는 단 한 줄도 나오지 않는다
모든 사물은 '존재의 이유'가 있다
모든 사물은 크든 작든, 그 크기에 맞는 명확한 책임이 있다
가위 - 자른다 / 연필 - 쓴다 / 망치 - 못을 박는다 등등
이 사물들은 각자 단 하나의 책임을 갖는다
가위로 못질을 하거나 연필로 구멍을 뚫는다면..? 매우 비효율적이고 위험하다
이 세상에는 단일책임원칙을 기반하여 설계를 했을 것이다
자른다, 쓴다, 박는다와 같은 행위들을 "책임"이라고 명명했는데 우리는 이걸 흔히 "기능"이라고도 한다
책임과 기능은 어떻게 다른것일까?
책임 VS 기능 : 혼동을 멈추는 명확한 구분법
책임과 기능을 혼동하기 쉽다.
좀 더 정교한 자연의 설계를 들여다보겠다
바로 우리 몸의 심장을 보면
하는 일 : 태어날 때부터 죽을 때까지 쉬지 않고 수축과 이완(펌프질)을 한다
이를 위해 스스로 전기 펄스를 일으키는 발전 기능을 수행하고, 혈액 유입량에 따라 박동의 세기를 조절한다
심지어 과부하가 걸리지 않도록 뇌와 통신하며 호로몬 분비에도 관여한다
여기서 많은 엔지니어가 혼란에 빠집니다
펌프질도 하고, 전기 스파크도 튀기고, 호로몬 조절도 하네?
기능이 벌써 3개 이상인데 SRP 위반 아닌가?
이 혼란은 책임과 기능을 구분하지 못해서 발생합니다
이 둘을 구분하는 가장 확실한 공식은 이것입니다
기능은 책임을 위해 존재한다
(Function exists for Responsibility)
심장의 수 많은 기능을 이 공식에 대입해 봅시다
1. 심박수 조절(기능)은 → 혈액 순환(책임)을 위해 존재한다. (O)
2. 전기 스파크 생성(기능)은 → 혈액 순환(책임)을 위해 존재한다. (O)
3. 유입량 조절을 위한 호르몬 분비(기능)는 → 혈액 순환(책임)을 위해 존재한다. (O)
모든 문장이 구조적 · 의미적으로 자연스럽게 성립합니다
이처럼 기능은 책임이라는 궁극적인 목표를 달성하기 위한 하위 수단일 뿐입니다
심장은 기능이 여러 개일지 몰라도 그 모든 기능이 가리키는 방향은 오직 혈액 순화이라는 단 하나의 책임입니다
반면 SRP를 위반하는 기능은 이 공식에 넣었을 때 말이 되지 않습니다
소화 효소 분비(기능)는 혈액 순환(책임)을 위해 존재한다
논리적으로 성립하지 않으므로 "소화 효소 분비"는 심장에 있어서는 안되는 기능입니다
내가 작성한 클래스나 모듈의 기능들을 이 문장에 대입해보고
문장이 어색하다면 그 기능은 잘못된 곳에 얹혀살고 있는 것입니다
왜 책임은 "하나"여야만 하는가?
기능들이 책임을 위해 잘 모여 있다면, 왜 그 책임은 단 하나여야 할까?
이를 이해하기 위해 억지스럽지만 과감한 상상을 해보겠습니다
만약 조물주가 설계를 잘못해서 심박 조절 기능을 심장이 아닌 폐에 구현했다고 가정
폐는 원래 '호흡'을 담당(책임)해야 하는데, 여기에 '심박 조절'이라는 기능이 추가된 것
심박 조절은 혈액 순환이라는 책임을 위해 존재하니 폐에 책임 하나가 더 추가된 것
느 날 여러분이 감기에 걸리거나 흡연 때문에 폐 기능이 나빠졌습니다.
그런데 폐가 심박 조절까지 담당하고 있으니, 폐렴에 걸렸을 뿐인데
갑자기 심장이 미친 듯이 뛰거나 멈춰버리는 '부작용(Side Effect)'이 발생
호흡기 질환이 순환기 질환으로 전이되는 끔찍한 결합(Coupling)이 생기는 것
SW 개발에서 우리가 가장 두려워하는 것이 바로 이것입니다.
하나를 건드렸는데 전혀 상관없어 보이는 다른 곳이 터지는 현상.
하나의 객체(기관)에 두 개 이상의 책임이 부여되면,
한 기능의 변경이나 손상이 다른 기능에 영향을 미칠 확률이 기하급수적으로 높아진다
우리가 "변경의 이유는 단 하나여야 한다"라고 말하는 이유가 바로 여기 있다
더 나아가, SRP의 창시자 로버트 C. 마틴은 훗날 SRP를
"모듈은 오직 하나의 액터(Actor=이해관계자)에 대해서만 책임져야 한다" 라고 재정의했다
이에 따르면 심장에 변화를 요구하는 액터는 '순환계'여야지, '호흡계'나 '소화계'여서는 안 된다
SRP 위반일까? 신의 Trade-off, 코와 혀가 보여주는 설계 선택
재미있는 건, 조물주도 완벽하지 않아서 SRP를 위반한 신체 기관들이 있다는 점이다
코 : 숨을 쉬는 통로, 냄새를 맡는 역할
혀 : 맛을 느끼는 역할, 발음을 만드는 역할
책임이 섞여 있으니 문제가 발생한다
감기에 걸려 코가 막히면 냄새도 못 맡게 된다
혀에 염증이 생기면 맛을 못보고 말하기도 불편해진다
만약 심장, 폐, 위장, 대장이 하나의 거대한 기관으로 뭉쳐져 있다면?
소화 불량으로 체했을 뿐인데 호흡이 멈추고 심장이 멎는 대참사가 발생할 수 있지만
우리 몸은 각자의 역할별로 책임이 격리되어 있어, 배탈이 났다고해서 호흡 곤란이 오지는 XX
이것이 단 하나의 책임을 갖도록 기관을 분리하는 아주 중요한 이유
하지만 흥미롭게도 자연은 공간 제약이나 생존 효율성을 위해 책임을 병합하기도 함
어쩌면 코가 숨을 쉬는 통로이기 때문에 후각 세포를 코 안쪽에 배치해 효율성을 선택
또한 코가 막히면 숨을 못 쉴 수 있다는 리스크가 있으므로
기도를 코와 입 양쪽에 연결해 리스크를 줄이는 설계를 선택했을 수도 있습니다
이 글에서는 단일책임원칙을 강조하고 있지만 그게 항상 만능은 아님
중요한 것은 'Trade-off’를 인지하고 있느냐'
현실 세계의 SRP : 명백한 위반부터 애매한 경계까지
그렇다면 우리가 흔히 접하는 물건들 중에 SRP를 위반한 사례는 없을까??
1) 추억의 '비디오 일체형 TV'
옛날에 TV와 비디오테이프 재생기(VCR)가 합쳐진 제품이 있었습니다.
V와 VCR 기능은 서로 다른 책임의 축을 가집니다.
- TV: 방송 신호를 화면으로 표시
- VCR: 테이프 내용을 재생
이 둘을 내부 회로까지 묶어놓으니(Tight Coupling)
비디오 헤드가 고장 나서 수리를 맡기면 그 기간 동안 뉴스도 못 보는(TV 기능 마비) 사태가 벌어짐
얼마 후 비디오 시대가 저물고 DVD 시대가 옴 ➡️
TV 화면은 아직 10년은 더 쓸 수 있는데, 비디오 데크가 쓸모 없어졌다는 이유로
거대한 TV 자체를 버려야 하는 비효율이 발생
책임의 프랙탈 : 세포부터 신체 시스템까지
서두에서 "모든 것은 크면 큰 대로, 작으면 작은 대로 그 크기에 맞는 책임이 있다"
이 문장은 SW 아키텍처의 핵심인 '추상화 레벨(Level of Abstraction)'과 직결됨
단일책임원칙은 단순히 클래스 하나에만 적용되는 규칙이 아님
아주 작은 단위부터 거대한 시스템 단위까지, 마치 프랙탈(Fractal) 구조처럼 동일하게 적용
세포(Function/Method 레벨)
▪️심장 근육을 이루는 세포 하나를 생각.
이 세포의 책임은 아주 작고 구체적일 것.
세포 하나가 혈액 순환 전체의 흐름을 고민하지 XX
▪️SW에서의 적용 : 함수나 메서드는 반복문, 조건문, 변수 할당 같은 가장 구체적인 책임을 짐
기관(Object/Class 레벨)
▪️수많은 세포가 모여 심장이라는 기관을 이룸
이제 책임의 크기가 커짐 : 단순 수축이 아니라 '혈액을 펌프질하여 순환시킨다'는 더 높은 차원의 책임을 가짐
심장은 세포들의 구체적인 수축 원리를 캡슐화(Encapsulation)하여 감추고 펌프라는 기능만 제공
▪️SW에서의 적용: 객체는 데이터를 관리하고 상태를 변경하는 비즈니스 로직 단위의 책임을 짐
신체 시스템(Component/Package 레벨)
▪️심장, 혈관, 혈액이 모여 '순환계(Circulatory System)'를 이룸
여기서 책임은 더 추상적입니다. '신체 전체에 산소와 영양분을 공급한다'는 거시적인 목표
▪️SW에서의 적용: 패키지나 모듈은 '결제 시스템', '회원 관리' 같은 큰 기능 단위의 책임을 짐
'🍏 개발일기' 카테고리의 다른 글
| CSV 파일을 활용한 온도 데이터 시각화 (0) | 2026.03.17 |
|---|---|
| “이 장애, 얼마나 심각한가요?” 사용자 경험을 기준으로 비즈니스 심각도를 정의하다를 읽으며.. (0) | 2026.03.15 |
| Python CSV 데이터 분석 기초 (0) | 2026.03.13 |
| 웹에서 사용자 상태(로그인 정보 등)를 유지하기 위해 사용하는 기술 : 세션과 쿠키 (0) | 2026.03.12 |
| python 다운로드 (0) | 2026.03.11 |