책임의 기본 단위는 객체를 지칭한다.
즉 객체는 단 하나의 책임만 가져야 한다는 의미다.
책임은 보통 ‘해야 하는 것’이나 ‘할 수 있는 것’으로 간주할 수 있다.
객체에 책임을 할당할 때는 어떤 객체보다도 작업을 잘 할수 있는 객체에 책임을 할당해야 한다.
class Student {
void getCourses() {} // 강의 get
void addCourse(Course c) {} // 강의 add
void save() {} // db 저장
Student load() {} // db 로드
void printOnReportCard() {} // 출력
void printOnAttendanceBook() {} // 출력
}
지금 Student 클래스는 너무 많은 책임을 수행한다.
Student 클래스는 수강 과목을 추가하고 조회하는 일을 가장 잘할 수 있다.
따라서 Student 클래스는 수강 과목을 추가하고 조회하는 책임만 수행하도록 하는 것이 SRP를 따르는 설계다.
class Student {
void getCourses() {}
void addCourse(Course c) {}
}
SRP를 실효성 있게 설계하려면 책임을 좀 더 현실적인 개념으로 파악해야한다.
설계 원칙을 학습하는 이유는 예측 못한 변경사항이 발생해도 유현하고 확장성이 있도록 시스템 구조를 설계하기 위해서다.
좋은 설계란 기본적으로 새로운 요구사항이나 변경이 있을 때 영향 받는 부분을 줄여야 한다.
위 Student 클래스의 변경 이유를 찾아보면 다음과 같다.
책임이 많아질수록 클래스 내부에서 서로 다른 역할을 수행하는 코드끼리 강하게 결합될 가능성이 높아진다.
Student 클래스는 여러 책임을 수행하므로 Student 클래스의 도움을 필요로 하는 코드도 많다.
Student 클래스에 변경사항이 생기면 직접 또는 간접적으로 사용하는 모든 코드를 다시 테스트해야 한다.
변경 사유가 될 수 있는 것은 하나로 만들어 하나의 책임만 수행하도록 변경해야 한다.
Student 클래스는 다음과 같이 개선할 수 있다.