"하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다."
액터란 시스템이 동일한 방식으로 (방향으로) 변경되길 원하는 집단이다.
Employee 라는 클래스가 아래와 같은 일을 하고 있다고 가정한다.
1번은 CFO, 2번은 COO, 3번은 CTO 에 대한 보고를 위해서 사용된다 (이들은 다른 액터이다)
일견 깔끔하게 잘 정리된 클래스로 보이지만, calculatePay() 매서드와 reportHours() 매서드가 업무 시간을 계산하는 알고리즘을 공유한다고 가정해보자. (regularHours())
이렇게 하나의 알고리즘이 다른 액터들에 의해서 중복되어 사용되게 된다면 어떤 점이 좋지 않을까?
회계팀이 초과 근무를 제외한 업무 시간을 계산하는 방식을 약간 수정하기로 한다면?
이 액터는 regularHours() 라는 공통된 알고리즘에 수정을 가한다.
그러나 다른 액터 측에서는 이 변경 사실을 알기 어렵다
따라서 reportHours() 수행으로 얻어진 결과는 오염되고, 이 결과를 신뢰 할 수 없게 된다. 대부분 이 오염은 빠르게 캐치되지 못한다.
일반적으로 회원이 해야 할 일을 회원 클래스가 가지고 있는 것에 대해서 이상함을 느끼지 못한다. (실세계에 비춰 생각했을 때)
위와 같은 상황이 문제가 되는 이유는 클래스 스스로가 데이터의 변조 (어떠한 알고리즘에 의한 상태값의 변경) 라는 일을 수행하고 있고, 이 변조가 다른 액터들에게 영향을 끼치고 있기 때문이다.
따라서 책에서는 아래와 같은 해결책을 제시한다.
앞선 장에서 저자가 생각한 객체지향 언어들 (내가 사용하는 Java 라던지) 에 대한 생각을 아주 흥미롭게 표현했는데, 그 중 인상깊었던 것 중 하나는 객체지향 언어가 캡슐화, 상속, 다형성 중 향상시킨 것은 다형성 뿐이다 라는 아이디어이다.
실제로 나는 객체지향을 위해서 개발자가 가장 신경써야 할 것은 캡슐화라고 생각하는데, 이는 "다형성" 이라는 컨셉이 언어 레벨에서 충분히 많이 지원되고 있고, (일반적으로 많이 사용하는 프레임워크인 스프링에서도 아주 강력한 다형성 - IOC, ... 를 제공한다) 상속은 아주 특별한 상황에서만 사용되고 있기 때문이다.
SRP의 아이디어는 "하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다." 이다. 결론적으로 이 액터의 모든 행위(Method) 공유되는 데이터나 함수의 유무와 관계 없이 관리되어야 하고, 잘 설계된 캡슐화에 의해서 보호되어야 한다.