[Clean Architecture] 7장. SRP: 단일 책임 원칙
|Introduction
- SOLID 원칙 중 그 의미가 가장 잘 전달되지 못한 원칙은 바로 단일 책임 원칙 (SRP)
- 역사적으로 SRP 는 아래와 같이 기술되어 왔다.
단일 모듈은 변경의 이유가 하나, 오직 하나뿐이어야 한다.
- 소프트웨어 시스템은 사용자와 이해관계자를 만족시키기 위해 변경됨
- SRP 가 말하는 ‘변경의 이유’란 바로 이들 사용자와 이해관계자를 가리킴
- 아래와 같이 바꿔 말할 수 있음
하나의 모듈은 하나의, 오직 하나의 사용자 또는 이해관계자에 대해서만 책임져야 한다.
- 여기서 해당 변경을 요청하는 한 명 이상의 사람들, 집단을 액터 (actor) 라고 부르면 아래처럼 최종 버전이 된다.
하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다.
- 그럼 모듈은?
- 가장 단순한 정의는 소스 파일
- 대부분의 경우 이 정의는 잘 들어맞음
- 모듈은 단순히 함수와 데이터 구조로 구성된 응집된 집합
- ‘응집된 (cohesive)’ 이라는 단어가 SRP 를 암시함
- 단일 액터를 책임지는 코드를 함께 묶어주는 힘이 바로 응집성(cohesion) 이다.
- 가장 단순한 정의는 소스 파일
- 아마도 이 원칙을 이해하는 가장 좋은 방법은 이 원칙을 위반하는 징후들을 살펴보는 일
징후 1: 우발적 중복
- 급여 애플리케이션의
Employee
클래스calculatePay()
,reportHours()
,save()
라는 메서드를 가진다.
- 이 클래스는 SRP 를 위반
- Why?
calculatePay()
- 회계팀에서 기능을 정의함
- CFO 보고를 위해 사용
reportHours()
- 인사팀에서 기능을 정의
- COO 보고를 위해 사용
save()
- DBA가 기능을 정의
- CTO 보고를 위해 사용
- 단일 클래스에 세 액터가 서로 결합됨
- 이로 인해 다른 액터에서 결정된 조치가 또 다른 액터에 영향을 미칠 수 있게됨
- 예를 들어
calculatePay()
,reportHours()
에서 공통적으로 초과 근무를 제외한 업무 시간을 계산하는 알고리즘을 공유한다면?- 영향을 서로 영향을 끼치게 됨
- SRP 는 서로 다른 액터가 의존하는 코드를 서로 분리하라고 말함
징후 2: 병합
- 만약 메서드가 서로 다른 액터를 책임진다면, 병합이 발생할 가능성이 높아진다.
- 매우 당연한 얘기
- 병합에는 항상 위험이 따르게 된다.
- 이 징후는 많은 사람이 서로 다른 목적으로 동일한 소스 파일을 변경하는 경우에 해당
- 이 문제를 벗어나는 방법은 서로 다른 액터를 뒷받침하는 코드를 서로 분리하는 것
해결책
- 가장 확실한 해결책은 데이터와 메서드를 분리하는 방식
- 즉, 아무런 메서드가 없는 간단한 데이터 구조인 EmployeeData 클래스를 만들어, 세 개의 클래스가 공유하도록 한다.
- 각, 클래스는 자신의 메서드에 반드시 필요한 소스 코드만 포함한다.
- 세 클래스는 서로의 존재를 몰라야 한다.
- 따라서 ‘우연한 중복’을 피할 수 있다.
- 하지만 이 해결책은 개발자가 세 가지 클래스를 인스턴스화하고 추적해야 하는게 단점
- 이러한 난관을 빠져나올 때 흔히 쓰는 기법으로 Facade 패턴이 있다.
- 어떤 개발자는 가장 중요한 업무 규칙을 데이터와 가깝게 배치하는 방식을 선호한다
- 이 경우라면 가장 중요한 메서드는 기존의 Employee 클래스에 그대로 유지하되
- Employee 클래스를 덜 중요한 나머지 메서드들에 대한 퍼사드로 사용할 수 도 있다.
- 이러면 모든 클래스는 반드시 단 하나의 메서드를 가져야 한다는 주장에 근거하여 안되지 않나?
- 하지만 이 주장은 현실과는 다르다.
- 여러 메서드가 하나의 가족을 이루고, 메서드 가족을 포함하는 각 클래스는 하나의 유효범위가 됨
- 해당 유효범위 바깥에서는 이 가족에게 감춰진 private 멤버가 있는지 전혀 알 수 없음
결론
- 단일 책임 원칙은 메서드와 클래스 수준의 원칙
- 하지만 이보다 상위의 두 수준에서도 다른 형태로 다시 등장함
- 컴포넌트 수준에서는 공통 폐쇄 원칙이 됨
- 아키텍처 수준에서는 아키텍처 경계의 생성을 책임지는 변경의 축이 됨
- 이런 개념에 대해서는 이후의 장에서 살펴볼 예정