SOLID 원칙 중에서 그 의미가 가장 잘 전달되지 못한 원칙은 바로 단일 책임 원칙이다

아마도 현저히 부적절한 이름 때문이기도 할 것이다

프로그래머가 이 원칙의 이름을 듣는다면 모든 모듈이 단 하나의 일만 해야 한다는 의미로 받아들이기 쉽다

헷갈리지 말라 단 하나의 일만 해야 한다는 원칙은 사실 따로 있다 그것은 바로 함수는 반드시 하나의, 단하나의 일만 해야한다는 원칙이다

이 원칙은 커다란 함수를 작은 함수들로 리팩터링하는 더 저수준에서 사용된다

하지만 이 원칙은 SOLID 원칙이 아니며, SRP도 아니다


역사적으로 SRP는 아래와 같이 기술되어 왔다

"단일 모듈은 변경의 이유가 하나, 오직 하나뿐이어야 한다"


소프트웨어 시스템은 사용자와 이해관계자를 만족시키기 위해 변경된다

SRP가 말하는 변경의 이유란 바로 이들 사용자와 이해관계자를 가리킨다 사실 이 원칙은 아래와 같이 바꿔 말할 수도 있다

"하나의 모듈은 하나의, 오직 하나의 사용자 또는 이해관계자에 대해서만 책임져야 한다"


...


calculatePay() 메서드는 회계팀에서 기능을 정의하며, CFO 보고를 위해 사용한다

reposrtHours() 메서드는 인사팀에서 기능을 정의하고 사용하며, COO 보고를 위해 사용한다

save() 메서드는 DBA가 기능을 정의하고, CTO 보고를 위해 사용한다


개발자가 이 세 메서드를 Employee라는 단일 클래스에 배치하여 세 액터가 서로 결합되어 버렸다

이 결합으로 인해 CFO 팀에서 결정한 조치가 COO팀이 의존하는 무언가에 영향을 줄 수 있다


예를 들어 calculatePay() 메서드와 reportHours() 메서드가 초과근무를 제외한 업무 시간을 계산하는 알고리즘을 공유한다고 해보자

그리고 개발자는 코드 중복을 피하기 위해 이 알고리즘을 regularHours()라는 메서드에 넣었다고 해보자


이제 CFO 팀에서 초과 근무를 제외한 업무 시간을 계산하는 방식을 약간 수정하기로 결정했다고 하자, 반면 인사를 담당하는 COO 팀에서는

초과 근무를 제외한 업무 시간을 CFO 팀과는 다른 목적으로 사용하기 떄문에, 이 같은 변경을 원하지 않는다고 해보자


이 변경을 적용하는 업무를 할당받은 개발자는 calculatePay() 메서드가 편의 메서드인 regularHours()를 호출한다는 사실을 발견한다

하지만 안타깝게도 이 함수가 reportHours() 메서드에서도 호출된다는 사실은 눈치채지 못한다


개발자는 요청된 변경사항을 적용하고 신중하게 테스트한다 CFO 팀은 새로운 메서드가 원하는 방식으로 동작하는지 검증하고, 시스템은 배포된다

물론 COO 팀에서는 이러한 일이 벌어지고 있다는 사실을 알지 못한다

COO 팀 직원은 reportHours() 메서드가 생성한 보고서를 여전히 이용한다

하지만 이제 이 보고서에 포함된 수치들은 엉터리다 마침내 문제가 발견되고 COO는 격노한다