리셋 되지 말자

SRP-단일 책임 원칙 본문

Java(폐지)/객체지향 설계 5원칙-SOLID

SRP-단일 책임 원칙

kyeongjun-dev 2020. 7. 20. 18:35

SRP-단일 책임 원칙

어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다" - 로버트 C. 마틴

잘 모르겠다. 예시를 들어보자.아래와 같이 남자라고 하는 클래스와 남자 클래스에 의존하는 다양한 클래스가 있다고 한다.

  • 남자가 역할이 너무 많다. 만약 남자가 여자친구와 헤어졌다고 하면, 기념일 챙기기, 키스하기는 더이상 필요가 없게 된다.
  • 이러한 경우에 역할(책임)을 분리하라는 것이 '단일 책임 원칙' 이다.

위의 예에서는 클래스에 단일 책임 원칙을 적용했지만 단일 책임 원칙은 속성, 메서드, 패키지, 모듈, 컴포넌트, 프레임워크 등에도 적용될 수 있는 개념이다.

예제1 - 속성이 단일 책임 원칙을 지키지 못하는 경우

  • 객체 지향 세계에서 남자는 군대에 가고, 여자는 절대 군대에 가지 않는다고 가정한다.
  • 사람 클래스에 군번 이라는 속성이 존재한다.
사람 남자 = new 사람();
사람 여자 = new 사람();
여자.군번 = "15224123" // ???

위처럼 여자인 경우에도 군번을 할당할 수 있는 상황이 발생하게 된다.

  • 리팩토링을 한다.
    1. 사람 클래스를 남자 클래스, 여자 클래스로 분리한다. -> 남자 클래스에만 군번 속성을 갖게 한다.
    2. 남자 클래스와 여자 클래스의 공통점이 없다면 사람 클래스를 삭제한다. 공통점이 많다면 사람 클래스를 남겨둔다.
    3. 남자 클래스와 여자 클래스는 사람 클래스를 상속하고 차이점만 각자 구현한다.

하나의 속성이 여러 의미를 갖는 경우도 단일 책임 원칙을 지키지 못하는 경우다.

예제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대 특성 중, 단일 책임 원익과 가장 관계가 깊은 특성은 모델링을 담당하는 '추상화'이다.

어플리케이션 경계를 정하고 추상화를 통해 클래스들을 선별하고 속성과 메서드를 설계할 때 반드시 단일 책임 원칙을 고려해야 한다. 또한 리팩터링을 통해 코드를 개선할 때도 단일 책임 원칙을 적용할 곳이 있는지 찾아낼 수 있어야 한다.

'Java(폐지) > 객체지향 설계 5원칙-SOLID' 카테고리의 다른 글

SRP와 ISP  (0) 2020.07.21
ISP - 인터페이스 분리 원칙  (0) 2020.07.21
LSP - 리스코프 치환 원칙  (0) 2020.07.20
OCP - 개방 폐쇄 원칙  (0) 2020.07.20
객체 지향 설계 5원칙 - SOLID  (0) 2020.07.20
Comments