Java(폐지)/객체지향 설계 5원칙-SOLID
SRP-단일 책임 원칙
kyeongjun-dev
2020. 7. 20. 18:35
SRP-단일 책임 원칙
어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다" - 로버트 C. 마틴
잘 모르겠다. 예시를 들어보자.아래와 같이 남자라고 하는 클래스와 남자 클래스에 의존하는 다양한 클래스가 있다고 한다.
- 남자가 역할이 너무 많다. 만약 남자가 여자친구와 헤어졌다고 하면, 기념일 챙기기, 키스하기는 더이상 필요가 없게 된다.
- 이러한 경우에 역할(책임)을 분리하라는 것이 '단일 책임 원칙' 이다.
위의 예에서는 클래스에 단일 책임 원칙을 적용했지만 단일 책임 원칙은 속성, 메서드, 패키지, 모듈, 컴포넌트, 프레임워크 등에도 적용될 수 있는 개념이다.
예제1 - 속성이 단일 책임 원칙을 지키지 못하는 경우
- 객체 지향 세계에서 남자는 군대에 가고, 여자는 절대 군대에 가지 않는다고 가정한다.
- 사람 클래스에 군번 이라는 속성이 존재한다.
사람 남자 = new 사람();
사람 여자 = new 사람();
여자.군번 = "15224123" // ???
위처럼 여자인 경우에도 군번을 할당할 수 있는 상황이 발생하게 된다.
- 리팩토링을 한다.
- 사람 클래스를 남자 클래스, 여자 클래스로 분리한다. -> 남자 클래스에만 군번 속성을 갖게 한다.
- 남자 클래스와 여자 클래스의 공통점이 없다면 사람 클래스를 삭제한다. 공통점이 많다면 사람 클래스를 남겨둔다.
- 남자 클래스와 여자 클래스는 사람 클래스를 상속하고 차이점만 각자 구현한다.
하나의 속성이 여러 의미를 갖는 경우도 단일 책임 원칙을 지키지 못하는 경우다.
예제2 - 메서드가 단일 책임 원칙을 지키지 못하는 경우
- 아래와 같은 강아지 클래스가 있다고 가정한다.
class 강아지 {
final static Boolean 수컷 = true;
final static Boolean 암컷 = false;
Boolean 성별;
void 소변보다() {
if(this.성별 == 수컷){
// 한쪽 다리를 들고 소변을 본다.
} else {
// 뒷다리 두 개를 굽혀 앉은 자세로 소변을 본다.
}
}
}
- 소변보다() 메서드에서 if문으로 분기처리가 되는 것을 확인할 수 있다.
-> 강아지 클래스의 소변보다() 메서드가 수컷 강아지의 행위와 암컷 강아지의 행위를 모두 구현하려고 하기에 단일 책임(행위) 원칙을 위배하는 것이다. - 리팩터링하면 아래와 같다.
abstract class 강아지 {
abstract void 소변보다();
}
class 수컷강아지 extends 강아지 {
void 소변보다(){
//한쪽 다리를 들고 소변을 본다.
}
}
class 암컷강아지 extends 강아지 {
void 소변보다(){
//뒷다리 두 개로 앉은 채 소변을 본다.
}
}
객체 지향 4대 특성 중, 단일 책임 원익과 가장 관계가 깊은 특성은 모델링을 담당하는 '추상화'이다.
어플리케이션 경계를 정하고 추상화를 통해 클래스들을 선별하고 속성과 메서드를 설계할 때 반드시 단일 책임 원칙을 고려해야 한다. 또한 리팩터링을 통해 코드를 개선할 때도 단일 책임 원칙을 적용할 곳이 있는지 찾아낼 수 있어야 한다.