SRP:
The Single Responsibility Principle / 단일 책임 원칙
None but Buddha himself must take the responsibility of giving out occult secrets...
— E. Cobham Brewer 1810–1897.
Dictionary of Phrase and Fable. 1898.
이 원칙은 1.Tom DeMarco와 2.Meilir Page-Jones에 작업에 의해 기술 되었고,
그들은 이것을 응집력이라고 불렀으며, 21챕터에서 볼 것으로써, 패키지 레벨에 응집력의 보다 명확한 정의를
다룰 것이지만 클래스 레벨상에 정의는 거의 비슷하다.
SRP: The Single Responsibility Principl
클래스를 변경하기 위한 하나 이상의 이유가 있어선 안된다.챕터 6에서 다룬 볼링 게임을 예를 들면 게임 클래스의 개발에 대부분을 위하여 2가지 책임을 분리해
다뤘는데, 현재 프레임에 트랙을 유지하는 것과 스코어를 계산하는 것이었다. 마지막으로는 RCM과
RSK라는 두개의 책임들을 두개의 클래스로 분리 해냈다.
Game은 프레임의 트렉 유지 책임을, Scorer는 스코어를 계산하는 책임을 유지했다. (85페이지)
1. [DeMarco79], p310
2. [PageJones88], Chapter 6, p82.
중요한 이러한 두 개의 책임들을 각각 분리된 클래스로 다루는 것이 왜 중요할까?
왜냐하면 각각의 책임들은 변동의 축이 되기 때문이다. 어떤 변동이 요구가 될 때, 그 변화는 클래스들 사이에
변동의 책임이라는것을 통해 명백하게 될 것이다. 만약 한 클래스가 한 개의 책임 이상을 가정한다면, 변동를 위해서는 한 개
이상의 이유가 있어야 할 것이다.
만약 한 클래스가 한 개 이상의 책임을 가진다면, 책임들은 상호간 결속되어 지는데,
한 개의 책임이 변하게 되면 다른 클래스들을 만나는 클래스적 기능이 감소되거나 방해가 될수 있으며,
이러한 종류의 상호간 결속력은 변동이 생길 때에 기대하지 않은 방향으로 쉽게 깨져버리게 된다.
예를들면, 9-1에서 사각형클래스에 두개의 메쏘드들을 보유하고 있고, 한개는 화면상에 사각형을 그리고, 다른 하나는 사각형
영역을 계산한다.
두개의 다른 응용프로그램이 사각형 클래스에서 사용된다.
우선 하나는 기하학적 계산을 하는데, 기하학 모형에 수학적 연산을 돕기위해 사각형클래스를 사용하여 사각형을 화면상에
그리지는 않는다.다른 응용프로그램은 그래픽적으로 작용하며 또한 기하학적인 연산처리를 하지만 명확한것은 화면상에 사각형을 그리는
역활을 한다.
이 클래스 디자인은 SRP(Single Responsibility Principle)을 어기고 있다.
사각형 클래스는 2개의 책임을 지고 있는데, 첫번째 책임은 사각형의 기하학적 모델의 수학적 부분을 제공하고,
두번째 책임은 그래픽적인 사용자 인터페이스 로써 사각형을 그리는 것이다.SRP를 어기는 것은 몇몇 귀찮은 문제들을 야기한다.
우선적으로, 기하학적 연산처리 응용 프로그램내에서 GUI를 포함해야만 하며,
만약 C++응용 프로그램이라면, GUI는 내부적으로, 메모리 추적, 컴파일 시간, 링크소비 시간을 링크를 해야 할 것이다.
자바 응용 프로그램이라면, .class파일들을 위한 GUI는 목표 플랫폼에 맞게 전개 되어야 한다.두번째로, 만약 몇가지 이유로 GraphiclaApplication의 변동이 사각형클래스의 변동을 야기 한다면, 그 변동은 강제적인 리빌드,
재검사, ComputationalGeometryApplication 이동을 요구 할 수도 있다.
만약 이것을 잊어버린다면, 그 응용 프로그램은 예측 불가능한 방향으로 돌변 할 수도 있다.더 나은 디자인은 참조 9-2에서 보여주는것처럼 완벽하게 다른 클래스들로 두개의 책임을 각각 분리 하는것이다.
이 디자인으로 사각형의 연산처리부분은 GeometricRectangle 클래스로 이동 되었다.
이제 변동으로 렌더링되는 사각형은 ComputationalGeometryApplication에 영향을 줄 수 없는 방법이 적용되었다.
여기서 이제 책임이 무엇인가?
구문상에 있어 단일 책임 원칙(SRP-Singlt Responsibility Principle)을 "변동을 위한 하나의 동기"를 책임으로 정의하였다.
만약 독자가 한클래스에 변동을 위한 한개의 동기 이상을 생각 한다면, 그 클래스는 한개 책임 이상을 가지게 된다.
이것은 때때로 어렵다. 여기 그룹내 책임을 생각하기 위해 익혀보도록 하자. 예로써 모뎀 인터페이스를 간주하였다.
Listing 9-1
Modem.java -- SRP Violation
interface Modem
{
public void dial(String pno);
public void hangup();
public void send(char c);
public char recv();
}
2개의 책임들이 여기서 보여진다. 첫째는 연결 관리이고, 두번째는 데이터 상호간 통신이다. dial과 hangup 함수는 모뎀의
연결을 관리하고 send, recv 함수는 통신을 관리한다. 이 두개의 책임들은 분리 되어야만 할까? 명확하게 그렇다.
두개의 셋 함수들은 거의 상호간 공통분모가 없다.
그것들은 각각 명확히 다른 이유의 변동이며, 거기다가 각각의 함수들을 사용하는 응용프로그램 부분까지 명확히 구획이
나누어져 호출된다. 이 두개의 서로다른 단위는 서로 다른 이유에 잘 변동이 될 것이다.
그러함으로 참조 9-3은 더 나은 클래스디자인을 보여준다. 그것은 두개의 분리된 인터페이스로 들어가는 책임들로 구분되어졌다.
이것은 적어도, 두개의 책임들의 연관성으로부터 클라이언트 프로그램을 유지시켜준다.
그러나, 주목할 것은 단일 ModemImplementation 클래스 내에 두개의 책임들이 재연관을 맺었다는 것 이다.
이것은 바람직하지 않지만 필요가 있다.
종종 어떤 하드웨어나 운영체제의 세부적인 사항들을 처리를 하기 위한 이유 등으로 인해 어쩔 수 없이 상호 연관을 가지게 되는
경우가 생긴다.
그러나, 그들의 인터페이스를 나눔으로 응용프로그램이 관련된 나머지에 관하여 개념적인 분리를 할 수가 있다.
ModemImplamentation 클래스는 적합하지 않을지도 모른다. 그러나 주목할 것은 모든 비독립적인 것들로 부터 멀리하라는
것이다.
Conclusion / 결론
단일 책임 원칙(Single Responsibility Principle) 은 하나의 단순한 원칙이고 올바르게 구현하기가 가장 어려운 디자인들 중
하나이다.
책임들을 결합 하는 것은 자연스러운 결과이며, 다른 하나로부터 여러 책임들을 찾아내고 분리해내는 것이 실제적인
소프트웨어 디자인의 상당 부분을 차지한다. 나머지 원칙들에 대해서 다루다 보면 한가지 또는 다른 방식으로 이 이슈가
다시 논의 될 것이다.
Bibliography
[DeMarco79]: Structured Analysis and System Specification, Tom DeMarco, Yourdon
Press Computing Series, 1979
[PageJones88]: The Practical Guide to Structured Systems Design, 2d. ed., Meilir PageJones, Yourdon Press Computing Series, 1988
'Programming > Design' 카테고리의 다른 글
OCP : The Open-Closed Principle (0) | 2011.08.05 |
---|---|
상속클래스에서 재정의 되는 인터페이스 메서드 (0) | 2011.07.18 |