Robert.C.Martin 블로그 번역-1 : 단일 책임 원칙(The Single Responsibility Principle)

Jooho Son
8 min readOct 14, 2019

--

본 문서는 Robert.C.Martin(AKA Uncle Bob)님의 블로그 포스팅인

The Single Responsibility Principle을 번역한 문서입니다.

마틴 옹께는 별도로 연락하여 허락을 받았습니다.

원문 링크:
https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html

1972년 David L. Parnas는 ACM(Association for Computing Machinery: 미 컴퓨터 협회)의 12월 이슈 Volumne 15의 12번에서 “On the Criteria To Be Used in Decomposing Systems into Modules” 라는 고전적인 문서를 출간 했다(직역: 시스템을 모듈로 분류하기 위한 기준)

이 문서에서 Parnas 는 로직(logic) 내부의 단순 알고리즘들을 나누고 분할하는 두가지 전략을 비교하였다.

해당 문서는 굉장히 매력적이고 꼭 공부해보기를 강력하게 권한다.

Parnas의 결론의 일부분은 아래와 같다.

“우리는 시스템을 모듈화 하는 것을 플로우 차트에 기반하는 것은 옳지 못하다는 것을 증명하고자 노력했었다.

대신에,결정내리기 어려운 설계의 목록과 앞으로 변할 것 같은 부분을 기준으로 설계적 결정들을 내리는것을 추천한다.

(설계:Design)

그렇게 한다면 각 모듈들은 이러한 결정들을 다른 모듈로부터 숨기며 설계 될수 있다.”

나(Robert.C.Martin)는 마지막에서 2번째 문장을 강조한다.

(강조 문장 원문: We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change)

Parnas의 결론은, 모듈이 변경될 수 있는 방식에 따라 최소한 부분적으로 분할 되어야 한다는 것이었다.

2년 후 Edsger Dijkstra 는 또다른 고전적인 문서인 On the role of scientific Thought 를 발간했고, 여기서 그는 관심사의 분할(The Separation of Concerns)이라는 용어를 소개했다.

1970~80 년대는 소프트웨어 아키텍쳐와 원칙들에 대해서 풍요로운 시기였다.

구조화된 프로그래밍과 설계들이 대두되었고, 해당 시기에 결합도(Coupling)와 응집도(Cohesion) 같은 개념들이 Larry Constantine 에 의해 소개되고, Tom DeMarco, Meilir Page-Jones 등의 사람들에 의해서 확장 되었다.

1990년대에 나(Robert.C.Martin)는 결합도(coupling), 응집도(cohesion)와 같은 개념들을 단일 책임 원칙(The Single Responsibility Principle)이라고 명명한 원칙으로 통합시키고자 했다.

(Bertrand Meyer에게서 원칙의 이름을 훔쳤지만, 허락받지 못한것에 대해서 찜찜함을 느끼고 있다. 원문 : I have this vague feeling that I stole the name of this principle from Bertrand Meyer, but I have not been able to confirm that.)

단일 책임 원칙에 따르면 각 소프트웨어 모듈은 변경사항이 단 한가지 이유에서만 발생해야 한다.

굉장히 듣기 좋은 말이고, Parnas의 표현과도 얼추 일치하는것 같다.

하지만, 위의 문장은 “어떤 것이 변경사항이 발생할 이유를 정의하는가?” 라는 질문을 시작하게 한다.

버그 수정 또는 리팩토링이 변경 사항 발생의 이유가 될 수 있지 않을까 의문을 가지는 사람이 있지만, 이러한 의문은 ‘변경의 이유’와 ‘책임’간의 연관성을 짚어 보면 답을 알 수 있다.

명확하게 표현하자면, 버그 수정이나, 리팩토링에 책임을 지지 않는다.

이와 같은 것들은 프로그래머의 책임이지 프로그램의 책임이 아니다.

그렇다면, 어떤 것이 프로그램의 책임일까?

좀 더 나은 표현은 누가 프로그램에 대한 책임을 질까?

더 나은 표현은,누가 프로그램의 설계에 대해서 답해줘야 할까?

전형적인 사업을 운영하는 회사를 상상해보자.

CEO가 가장 최상위에 있고, CFO, COO, CTO등과 같은 C-level의 경영진들은 CEO에게 보고 할 것이다.

CFO는 회사의 재무를 관리하는데 책임이 있고, COO는 회사 운영 및 관리에 책임이 있다.

그리고 CTO는 회사의 기술 환경 및 개발에 대한 책임이 있다.

이제 하단의 자바 형식으로 만든 임시코드에 대해 생각해보자.

public class Employee {public Money calculatePay();public void save();public String reportHours();}
  • calculatePay 메소드는 각각의 직원이 직급, 계약, 근무 시간등을 통해서 급여를 얼만큼 지급 받아야 하는지 측정하는 알고리즘을 포함하고 있다.
  • save 메소드는 데이터 베이스에 Employee 객체를 통해서 관리되는 데이터를 저장한다.
  • reportHours 메소드는 회계 담당자가 직원들이 알맞는 시간만큼 일을 했고, 적절한 보상을 지급 받을 수 있도록 보고서에 삽입될 문장 들을 반환한다.

자 이제 CEO에게 보고하는 C-level 경영진중 누가 calculatePay 메소드의 동작을 설계하는 것에 책임을 지는가?

만약 calculatePay 메소드에 중대한 설계상의 오류가있다면, 누가 CEO에 의해서 해고[1]를 당할까?

명확하게 말해서, 답은 CFO다.

직원의 급여를 결정하는 것은 재무의 책임이다. 만약 모든 직원들이 CFO의 조직의 누군가 급여를 계산하는 규칙을 잘못 정해서 2배의 급여를 받았다면, CFO는 해고를 당할 수 도 있다.

save 메소드에 중대한 설계상의 오류가 있다면, C-level경영진중 누가 해고 될 지는 명확하다.

기업의 데이터 베이스가 잘못된 정의로 인해 오류를 발생 시킨다면 CTO가 해고를 당하게 될 것이다.

이러한 이유에서, calculatePay 메소드의 알고리즘에 변경이 발생한다면, CFO가 이끄는 조직에 의해 변경사항이 요청되어야한다.

reportHours 메소드역시 COO의 조직에 의해서 변경사항이 요청되어야 하고, CTO의 조직은 save 메소드에 대한 변경사항을 요청할 것이다.

그리고 이런 부분들이 단일 책임 원칙을 복잡하게 만든다.

단일 책임 원칙은 사람에 관한 것이다.

(원문: This principle is about people)

당신이 소프트웨어 모듈을 만든다면, 변경사항이 요청될 때 어떤 한 사람, 또는 밀접 하게 연관된 집단이 단 하나의 비즈니스 기능을 세심하게 정의해서 요청하길 원하고,

모듈들이 전체적으로 조직의 복잡성으로 부터 독립되고 단 하나의 비즈니스 기능에 대해 대응하고, 책임지도록 시스템을 설계하고자 할것이다.

왜 그렇게 할까?

이유는 CTO가 요청한 변경사항으로 인해서 COO가 해고되기를 원하지 않기 때문이다.

고객과 관리자들은 요청한 변경사항들과는 완벽하게 무관한 프로그램의 오류를 과거와 같이 두려워 하지 않아도 된다.

만약 당신이 calculatePay 메소드를 수정했는데 의도치 않게 reportHours 메소드가 동작하지 않는다면 COO는 당신에게 calculatePay메소드를 수정하지 말라고 압박을 가하기 시작할 것이다.

자동차의 창문을 고치기 위해 정비사에게 차를 가져갔다고 상상해보자.
다음날 정비사는 창문이 고쳐졌다고 전화를 했다.
차량을 가지러 갔을 때 창문이 잘 동작한다는 것을 확인했지만, 시동이 걸리지 않는다.
그러면 당신은 그 정비사가 멍청하다고 생각하고 그에게 차량을 다시 맡기지 않을 것이다.

이것이 고객과 관리자들이 우리에게 변경해달라고 하지 않은 부분이 동작하지 않을 때 느끼는 감정이다.

그렇기 때문에, 우리는 JSP 내부에 SQL을 넣지 않고, HTML 모듈을 계산된 결과를 통해서 생성하지 않으며, 비즈니스 규칙을 데이터베이스 스키마와 분리하고,

관심사를 분리(Separate Concern)하는 것이다.

단일 책임 원칙에 관한 다른 표현을 보자.

“같은 이유에서 변경되는 것들을 모으고, 다른 이유에 의해서 변경되는 것들을 분할 한다”

(원문 : Gather together the things that change for the same reasons. Separate those things that change for different reasons)

이 표현에 대해 생각해 본다면, 응집도(cohesion)와 결합도(coupling)에 관한 또 다른 정의라는 것을 깨달을 수 있다.

우리는 같은 원인에 의해서 변경되는 부분들 간의 응집도(cohesion)를 높이고 싶어하고, 다른 원인에 의해서 변경되는 부분들 간의 결합도(coupling)는 낮추고 싶어한다.

당신이 이 원칙에 대해서 생각한다면, 변경의 원인은 사람에 있다는 것을 기억해라.

원인은, 변경사항을 요청하는 누군가이다.

다수의 사람들의 서로 다른 원인들을 한 코드에 섞어서 자기 자신, 다른 사람들이 혼란에 빠지는 것을 원하지는 않을것이다.

해고[1]
약간의 과장적인 표현이 섞여 있다.
C-level 경영진은 일반적으로 작은 정의 오류로 인해서 해고를 당하지는 않는다.
하지만, 가능성이 없는 일은 아니며, C-level경영진에게 보고하는 각 조직들은 각각 다른 관심사를 가지고 있다는 것을 강조하고자 했다.

--

--

Jooho Son

백엔드 개발자 입니다. 현재는 작고 소중한 스타트업에서 바라는 문화를 만들어 보고자 함께하고 있습니다. Backend Software Developer who works in small startup in South Korea. contact: joohotheman@gmail.com