단일 책임 원칙: 논쟁의 핵심은 규칙 그 자체가 아니었다
요약
단일 책임 원칙(SRP)의 핵심은 단순한 규칙 준수가 아니라 모호한 경계를 명확히 하는 것입니다. 함수 이름 테스트와 액터 질문을 통해 책임의 경계를 정의하고, AI 에이전트 시대에 더욱 중요해진 코드 구조의 설계 원칙을 다룹니다.
핵심 포인트
- 함수 이름에 'and'가 포함된다면 두 가지 이상의 책임을 가질 가능성이 높음
- 모듈은 단 하나의 액터(변경 주체)에게만 책임을 져야 함
- 코드 길이 제한은 대리 지표일 뿐, 실제 책임의 경계를 정의하지 못함
- AI 에이전트가 코드를 작성하는 환경에서는 모호한 경계가 더 큰 문제를 야기함
원칙적으로 단일 책임 (Single Responsibility)에 반대하는 사람은 없습니다. 제가 함께 일해온 모든 개발자는 함수가 한 가지 일만 해야 한다는 점에 동의합니다. 논쟁은 항상 예시에서 발생합니다. 예를 들어 processOrder가 한 가지 일인지 아니면 여섯 가지 일인지에 대한 논쟁이며, 이는 규칙 그 자체로는 해결할 수 없는 부분입니다.
이름 테스트 (The name test)
함수가 하는 일을 설명하기 위해 "그리고 (and)"가 필요하다면, 그것은 두 가지 작업입니다. 이는 가볍게 들릴 수 있지만, 제가 시도해 본 대부분의 방법보다 코드 리뷰에서 더 잘 통합니다. 주로 소리 내어 말하는 과정이 설명을 정직하게 만들기 때문입니다. validateAndSubmit은 하나의 이름을 공유하는 두 가지 작업입니다. 일단 "주문을 검증하고(validate) 나서 제출한다(submit)"라고 말하고 나면, 추출 (extraction)은 명확해지며 아무도 코드 라인 수에 대해 논쟁할 필요가 없습니다.
액터 질문 (The actor question)
더 날카로운 버전은 Robert C. Martin의 Clean Architecture에서 나옵니다: 모듈은 단 하나, 오직 하나의 액터 (actor)에게만 책임을 져야 합니다. 리뷰 단계에서 이는 "이 코드가 변경될 때 누가 비용을 지불하는가"의 문제로 바뀝니다. 동일한 함수에 대해 두 그룹의 사람들이 버그를 보고한다면, 그 함수가 아무리 짧더라도 그것은 경계 (boundary) 문제입니다.
David Parnas는 1972년에 '책임'이라는 단어를 사용하지 않고도 동일한 결론에 도달했습니다. 그는 변경될 가능성이 있는 설계 결정 사항들을 나열하고, 각각의 결정을 숨길 수 있는 모듈을 부여했습니다. 어휘는 다르지만 같은 맥락입니다.
길이 제한은 대리 지표일 뿐이다 (Length limits are proxies)
저는 함수당 최대 라인 수 (max-lines-per-function), 복잡도 (complexity), 그리고 최대 파라미터 수 (max-params)를 실행하며, 이는 엉킨 코드들을 조기에 잡아냅니다. 하지만 이것들이 규칙을 정의하지는 않습니다. 변경해야 할 이유가 단 하나뿐인 긴 함수는 괜찮지만, 두 팀을 위해 서비스하는 짧은 함수는 괜찮지 않습니다. 린터 (linter)는 냄새 (smell)를 감지하지만, 그 작업이 무엇인지 말하는 것은 여전히 사람의 몫입니다.
에이전트 (agents)의 등장으로 왜 더 날카로워졌는가
모호한 경계를 읽는 개발자는 주변 코드를 통해 의도를 파악합니다. 하지만 에이전트 (agent)는 그 경계를 기정사실로 받아들이고 그 위에 코드를 구축합니다. 누군가 문제를 알아차렸을 때는, 이미 나쁜 구조가 사실이라고 가정하며 성장해버린 코드가 존재하게 됩니다.
반론과 TypeScript, JavaScript, Python, Java 및 PHP를 위한 강제 설정(enforcement config)을 포함한 전체 글은 다음 링크에서 확인할 수 있습니다: https://prickles.org/tenet/single-responsibility-principle/F1
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기