본문 바로가기
Development/JAVA

[GOF 디자인패턴]단일책임(Solid)의 원칙

by True Life 2016. 12. 24.


[GOF 디자인패턴]단일책임(Solid)의 원칙


객체지향에는 단일책임의 원칙이 있다.

이는 SRP원칙이라고도 하는데 Single Responsibility Principle의 약자이다.


말그대로 객체지향에서 한 객체는 단일 책임을 가져야 한다는 말인데..

여기서 책임이란

1. 해야 하는 것

2. 할 수 있는 것

3. 해야 하는 것을 잘 할 수 있는 것


정도로 해석하면 될 것 같다.


예를 들어보자.





Student 객체에 대한 각 메소드 선언을 보면 이 Student클래스의 책임을 알 수 있다.


누가 생각해도 Student에서 DB를 건드리거나 (JDBC Connection)

텍스트 파일 리포팅을 하거나, pdf 변환 후 리포팅을 하던가 (File I/O)

이런건 타당치 않다.


여기 Student 객체에 대한 단일 책임은.

이 객체는 수강과목을 추가하고 조회하는 책임만 수행하도록 하는 것이 SRP를 따르는 설계이다.



우리가 왜 설계를 하는가.

설계는 개발단계에서도 필요하지만 추후 변경에 원칙을 적용할 수 있어 매우 용이하다.


책임 = 변경이유 라고 할 수도 있는데..


현재 상단의 Student객체는 언제 변경되어야 하는가.

이 이유를 찾아보자.


1. 데이터베이스 스키마가 변경될 경우

2. 학생이 지도 교수를 찾는 기능을 추가해야 할 경우

3. 성적표와 출석부 이외의 형식으로 출력해야 할 경우


너무 쓸데없이 많다.


따라서 책임분리의 원칙이 필요하며 이외의 기능은 다른 객체를 사용하던

(이를테면 DBManager내 reportStudentContent( ... ) )

(출석부, 성적표 클래스를 만드는 것도 하나의 방법인 것 같다)

이 클래스를 사용하는 클래스에서 처리하던 그건 Student와 별개라고 생각하지 않는가.


아무튼 이 원칙이 적용되면 DB의 스키마가 변경되던 출력 형태가 바뀌던 Student 클래스는 별.개이다


이런 종속성이 없으면 없을수록 추후 디버깅 및 수정에 용이함은 당연하다.


산탄총 수술

단일책임원칙에 대한 수정상황 중 하나이다. 매우 까다롭다.

객체 A에서 B1, B2, B3, B4 클래스를 호출한다고 하자.

이때 B1~4 객체의 생성자에 A클래스의 integer num이 들어가는데..

알고보니 이 num이 DB 스키마의 변경에 의해 String으로 바꿔야만 한다.


그러면 당연히 B1~4클래스의 생성자도 전부 수정해줘야 하는 상황이 발생한다.


이 수술이 위험한 이유는 수술 부위가 많다는 것만 아니라 모든 환부를 빠짐없이 찾아야 한다는 점이다.

이러한 예는 로깅, 보안, 트랜잭션과 같은 횡단관심(Cross-cutting concern)으로 분류할 수 있는 기능이 대표적이다.


횡단관심문제를 해결하기 위한 방법은

공통 책임을 한 곳에 모으면서 응집도를 높인다

라는 것인데.. 난 이 의미가 참 추상적이라고 생각한다.


개발에는 수 많은 상황이 발생하기 마련인데 그냥 공통 책임을 모은다는 것이 어디 쉬운일인가.

추후 발생될 버그,수정사항을 정확히 예측하지 않는 한

이 방법은 최고의 선책이 아니라 최선의 선택이 될 수 밖에 없다.


하지만

우리는 지금 최선의 선택을 말하고 있는 것이다.


이를 해결하는 방법을 일단 관심지향 프로그래밍이라고 한다.

이 기법은 횡단관심을 수행하는 코드를 ASPECT(관심)라는 특별한 객체로 모듈화하고

WEAVING(옆으로 움직이는것)이라는 작업을 통해 모듈화된 코드를 핵심기능에 끼워넣는다.


이를 통해 기존의 코드를 전혀 변경하지 않고도 시스템 핵심 기능에서 필요한 부가 기능을 효과적으로 이용할 수 있다.

만약 횡단관심에 변경이 생긴다면 해당 ASPECT만 수정하면 된다.


이게 무슨말이냐 하면..

기능을 다루는 객체를 만든다는 것이다.

어떻게 보면 Wrapper클래스라고 볼 수도 있지만 아무튼 어떤 객체로서의 역할이 아니더라도

기능으로서의 객체를 만들고 그 기능을 손보는 상황에서 해당 기능 객체만을 수정함으로 이해하면 편하다.


이는 단일책임의 원칙의 연장선인데

한 책임을 한 객체에 부여한다는 점에서 일맥상통하다


아무튼.. 화이팅!