단일 책임 원칙(Single Responsibility Principle)
http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39135552-1,00.htm

하나의 클래스는 하나의 책임만을 가져야 한다. 하나의 클래그 안에 필요에 의해 두 가지 책임이 공존할 때 서로의 의존관계는 심각하게 강결합도기 때문에 변경에 대한 충격이 전달될 수밖에 없다.

OCP는 확장이 설계의 포인트였다면, 단일 책임 원칙은 변경이 관전 포인트이다. 이 변경의 거북함을 조장하는 요소는 서로 다른 책임이 혼재해 있다는데 있다.

잘못된 설계 - 액티브 오브젝트 패턴

좋은 디자인 설계 - 데이터 맵퍼 패턴, 데이터 맵퍼를 사용하면 Person객체의 이용방식도 자연스럽게 DB관련 부분과 Person사용으로 분리된다.
사용자의 Person객체에 대한 책임을 사용하는 목적과 방법이 명확해진다.(Person객체의 인터페이스인지, DB관련 작업인지)

설계자는 분리의 크기(granularity)를 고민한다.
  • fine-grained : 미세단위로 구분
  • coarse-grained : 입도가 큰 단위로 구분
  • 선택의 기준은 복잡도,크기,용도가 된다. 복잡도가 높고 부피가 큰데 반해 그 용법이 단순하다면, coarse-grained가 적합하다. 역으로 복잡도가 낮고 부피가 작으며 용법이 다양하다면 fine-grained가 적합하다.
일반적인 식별자 맵패턴이 사용

높은 응집도(High Cohesion), 낮은 결합도(Loose Couplimng)
: 이것은 현재 모든 소프트웨어 시스템 고유의 유지보수성과 적응성을 측정하는 가장 좋은 방법으로 사용되고 있다. 소프트웨어 디자인 뿐만 아니라 아케텍쳐 평가에도 이 원리가 기준이 되는데, 그 이유는 이 원리의 적용 효과가 아주 명백하기 때문이다. 이 원리의 예외는 거의 찾아보기 힘들만큼 보편성을 가지고 있어서 마치 물리학의 엔트로피 법칙처럼 절대적인 기반원리를 제시한다. 반대로 낮은 응집도, 높은 결합도를 가지는 디자인은 변경,확장 단계에서 많은 비용을 지불해야 한다.
  • 응집도 : 하나의 클래스가 하나의 기능(책임)을 순도 높게 담당
    * 기능적 응집 - 일관된 기능들이 집합된 경우
    * 순차적 응집 - 한 클래스 내에 등장하는 하나의 소작업(메소드)의 결과가 다음 소작업의 입력으로 사용되는 관계(파이프라인 방식의 처리 체인 관계)
    * 교환적 응집 - 동일한 입력과 출력 자료를 제공하는 메소드들의 집합을 말하며, 팩토리 클래스는 전형적인 교환적 응집도가 높은 인터페이스를 갖는다.
    * 절차적 응집 - 순서적으로 처리되어야 하는 메소드들이 그 순서에 의해 정렬되는 응집관계
    * 시간적 응집 - 시간에 흐름에 따라 작업 순서가 정렬되는 응집관계
    * 논리적 응집 - 유사한 성격의 개체들이 모여 있을 경우를 말하며 java.io클래스들의 경우가 대표적인 예이다.
  • 결합도 : 클래스간의 서로 다른 책임들이 얽혀 있어서 상호의존도가 높은 정도
    * 자료 결합 - 두 개 이상의 클래스가 매개변수에 의해서 결합 관계를 가지므로 낮은 수준의 결합도로 연관되는 경우
    * 스탬프 결합 - 자료 결합의 경우에서 매개변수 일부만을 사용하는 경우
    * 제어 결합 - 두 클래스간이 제어 이동이 매개변수를 이용하여 사용되는 경우
    ex) Command Pattern
엔터프라이즈 애플리케이션 설계시 요소
  • -데이터 접근의 동기화
  • -동시성 처리
  • -풀링
  • -O/R 맵핑

--> 각 책임들을 담당하는 클래스들을 분리시키고 이들 간의 관계를 잘 정의할수록 복잡도는 감소하고 아키텍쳐는 깨끗해진다.


예를들면, 현재 제공되는 DB관련 프레임워크는 이 책임들을 맡는 기능을 구현한 녀석들이다. SRP를 적용하면 무엇보다도 책임 영역이 확실해지기 때문에 한 책임의 변경에서 다른 책임의 변경으로의 연쇄작용에서 자유로울 수 있다.

동일한 책임을 갖는 여러 메소드들이 분리된다.
ex) isnert, delete, update, load

여러 원인에 의한 변경 : 하나의 클래스에 책임이 혼재하고 있엉서 하나의 책임의 변화가 다른 책임에 영향을 준다.
  • Extract Class는 혼재된 각 책임을 각각의 개별 클래스로 분할하여 클래스 당 하나의 책임만을 맡도록 하는 것이다. 여기서 관건은 책임만 분리하는 것이 아니라 분리된 두 클래스간의 관계의 복잡도를 줄이도록 설계하는 것이다.
  • 만약 Extract Class된 각각의 클래스들이 유사하고 비슷한 책임을 중복해서 갖고 있다면 Extract Superclass를 사용할 수 있따. Extract class된 각각의 클래스들의 공유되는 요소를 부모 클래스로 정의하여 부모 클래스에 위임하는 기법이다.. 따라서 각각의 Extract Class들의 유사한 책임들은 부모에게 명백히 위임하고 다른 책임들은 각자에게 정의할 수 있다

산탄총 수술의 냄새는 하나의 책임이 여러 클래스에 분산되어 있기 때문에 발생한다.
특히 설정 정보, 로깅, DB처리에서 발생하기 쉽다.

'여러 원인에 의한 변경'과 '산탄성 수술'이란 악취를 SRP를 어긴 신호로 여기고 제거한다면 여러 곳으로 확산되지 않을 뿐 아니라 책임을 적절히 분배함으 인해 코드의 가독성 향상, 유지보수 용이라는 이점까지 누릴 수 있다. 적절한 책임 분배는 객체지향 원리들의 대전제 격인 OCP뿐 아니라 다른 원리들들 적용하는 기초가 되어준다.

핵심 리팩토링 기법과 책임 분배
: 할 수만 있다면, '사후 대처'보다는 '사전 예방'이 더 좋은 해결책이다.

SRP를 적용하면 클래스들의 숫자가 늘 수는 있다. 하지만, 클래스 숫자의 증가가 프로그램 복잡도 증가와 비례하는 것은 아니다. 오히려 SRP를 잘 따르는 프로그램은 절절한 책임 분배로 인해 클래스 숫자와 프로그램의 복잡도가 반비례하는 경향이 있다고도 할 수 있게 된다.

실제로 단순한 것이 위대한 것이다. 그리고 이 단순함의 중심에는 단일 책임의 원칙이 있다

Posted by ologist
 TAG ,

블로그 이미지
ologist

공지사항

Yesterday170
Today61
Total33,502

달력

 « |  » 2012.02
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

최근에 받은 트랙백

글 보관함