단일 책임 원칙(SRP)

: SRP(Single Responsibility Principle) 란 객체는 단 한 개의 책임(역할)만을 가져야 한다는 내용으로, 객체를 변경해야 하는 이유는 단 하나여야 한다는 원칙이다.

 

- 책임이란 해야 하는 것을 잘 할 수 있는 것이다.

 

- 객체가 여러 개의 책임을 가지고 있다면 결합도가 증가할 가능성이 높아 하나의 책임을 변경해야할 경우 다른 책임을 변경할 가능성이 생기게 된다. 즉, 시스템에 변경이 발생할 때 기존의 기능에 영향을 주는지 평가해야 하는 회귀 테스트를 해야한다.

 

ex1) Student(학생) 클래스가 수강 과목 추가/조회, db에 정보 저장/읽기, 성적부/출석부 출력하는 함수가 정의되었다고 가정하면 Student 클래스는 SRP에 따르면 한 개의 책임을 가져야 하는데 너무나 많은 책임을 가지고 있다. Student 클래스가 가장 잘 할 수 있고 해야 하는 것은 수강 과목 추가/조회이다. db 정보 저장/읽기나 성적부/출석부 출력은 다른 클래스가 더 잘 할 여지가 많다. 또한 변경해야 하는 이유는 단 하나여야 하는데 학생의 고유 정보, db 스키마, 출력 형식 변화 등으로 변경이 될 수 있다. 그래서 밑의 그림과 같이 변경하면 좋다.

 

 

 

- 산탄총 수술

하나의 책임이 여러 개의 클래스로 분산되어 있을 경우 단일 책임 원칙에 입각해 설계를 변경해야 하는데 이를 산탄총 수술이라고 한다. 산탄총은 하나의 총알에 여러 개의 탄이 들어있어 맞게 되면 여러 개의 탄들을 일일이 찾아서 치료해야 하기 때문이다. 즉, 어떤 변경이 있을 때 여러 클래스를 수정해야 한다. 예를 들어, 하나의 테이블을 조작하는 db처리문이 애플리케이션 전역에 퍼져 있는 상황에서 db 테이블의 구조가 바뀌게 되면 일일이 찾아서 수정해야 한다. 이와 같이 설정 정보, 로깅, db 처리에서 많이 발생하게 된다. 따라서 쓰레드, 커넥션, 오브텍트 풀의 크기 값이나 db/서버의 주소 정보들을 각각의 클래스에 자체적으로 관리하고 있는 게 좋고 별도의 유틸리티 클래스를 만들어 관리해도 괜찮다. 또한 AOP를 사용해도 된다.

 

 

ex2)

위 Displayer 클래스는 특정 파일로부터 내용을 읽어오는 readContent()와 내용을 화면에 출력하는 displayContent()함수를 가지고 있고 입력과 출력이라는 두 가지 책임을 가지고 있다. 나중에 위 클래스의 호응이 좋아 요구사항이 생겼다고 하자. 파일뿐만 아니라 db에서 내용을 읽기, PC화면 뿐만 아니라 모바일에서도 내용 출력 요구사항이다. 일단 위의 클래스가 SRP에 어긋나니 아래의 그림처럼 바꿨다.

 

책임에 따라 Displayer 클래스와 Reader 클래스로 바꿨다. 그리고 요구사항에 맞춰 아래의 그림처럼 할 수 있다.

 

+ Recent posts