SOLID 가장 첫 번째 단어인 단일 책임 원칙Single Responsibility Principle에 대해 알아보도록 하자.

단일 책임 원칙이란?

A CLASS SHOULD HAVE ONLY ONE REASON TO CHANGE.

Robert Martin. SRP: The Single Responsibility Principle.

클래스는 변경에 대한 한 가지 이유만을 가져야 한다. 다양한 이유로 클래스가 변경 되어서는 안된다. 예를 들어, 어떤 클래스가 비즈니스 규칙과 인프라스트럭처infrastructure(데이터 영속성 관리 등 비즈니스 규칙에 비해 변경 가능성이 낮은) 변화에 따라 함께 변경된다면 클래스는 분리될 필요가 있는 것이다. 변경에 대한 이유a reason for change 그리고 변경의 축an axis of change이 바로 책임responsibility이며, 단일 책임 원칙의 핵심이다.

책임이 분리되어야 하는 이유를 간단한 예제로 함께 설명해 보도록 하자.

그림 1. 한 가지 이상의 책임 (출처: https://goo.gl/HbixP9)

위 그림에서 Rectangle은 두 가지 책임을 가지고 있다. 하나는 스크린에 사각형을 그리는 렌더링rendering, 하나는 사각형의 넓이를 구하는 수학적 책임이다. 이 설계가 가져오는 문제는 2가지이다.

  1. ComputationalGeometryApplication이 GUI를 포함해야 한다.
  2. GraphicalApplication으로 인한 Rectangle의 변경이 ComputationalGeometryApplication에도 영향을 준다.

왜 ComputationalGeometryApplication는 GUI를 사용하지도 않는데 GUI를 포함해야 할까? 또, ComputationalGeometryApplication와 상관 없는 기능으로 Rectangle이 변경되었는데 왜 다시 테스트를 받아야 하는가? 테스트해야 한다는 사실을 모를 경우 예상치 못한 문제가 생길 수도 있는 노릇이다. 불필요한 의존성은 예상치 못한 비용을 불러온다.

그림 2. 분리된 책임 (출처: https://goo.gl/HbixP9)

위 그림은 책임을 분리한 결과이고, 이제 렌더링 관련된 기능이 ComputationalGeometryApplication에 더 이상 영향을 주지 않는다. 책임의 결합coupling은 깨지기 쉬운 디자인이다. 변경의 영향 범위를 파악하기가 어려워지고, 예상치 못한 곳에 문제를 일으킨다.

책임의 경계는 어디까지인가?

아래 인터페이스를 통해 책임의 경계에 대해 좀 더 생각해 보도록 하자.

public interface Modem {
    public void Dial(string pno);
    public void Hangup();
    public void Send(char c);
    public char Recv();
}

Modem이라는 클래스에는 2가지 책임이 있는 것 처럼 보인다. 하나는 연결 관리(Dial, Hangup)이고, 다른 하나는 데이터 통신(Send, Recv)이다. 그런데 정말 이 책임이 분리되어야 할까?

That depends upon how the application is changing. If the application changes in ways that affect the signature of the connection functions, then the design will smell of Rigidity because the classes that call send and read will have to be recompiled and redeployed more often than we like.

If, on the other hand, the application is not changing in ways that cause the the two responsibilities to change at different times, then there is no need to separate them. Indeed, separating them would smell of Needless Complexity.

Robert Martin. SRP: The Single Responsibility Principle.

로버트 마틴은 “어플리케이션이 어떻게 변하느냐에 따라 다르다”라고 이야기 한다. 만약 데이터 통신과 상관 없이 연결 관리 부분만 변경된다면 이는 경직성rigidity이고, 함께 변경되는 데도 불구하고 분리한다면 불필요한 복잡도Needless Complexity이다.

생각해 볼 거리

  • 변화를 얼마나 예측할 수 있는가?
  • 변경 이외에 책임을 정의하는 의미 있는 지표는 무엇인가?

참고 문헌

[1] Robert Martin. SRP: The Single Responsibility Principle.

관련 문서

[1] SOLID 개요
[2] 단일 책임 원칙 SRP
[3] 개방 폐쇄 법칙 OCP
[4] 리스코프 치환 법칙 LSP