본문으로 바로가기
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



SRP - 단일 책임 원칙 


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


작성된 클래스는 하나의 기능만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임을 수행하는 데 집중되어 있어야 한다는 원칙이 단일 책임 원칙이다.


남자는 남자친구의 역할, 아들, 군인, 사원의 역할등을 수행할 수 있다. 하지만 이렇게 되면 너무나 피곤하다. 역할과 책임이 너무 많아진다.



1
2
3
4
5
6
7
8
9
10
11
12
13
class Man {
    //Method List
    /*
     * 키스하기
     * 기념일 챙기기
     * 출근하기
     * 아부하기
     * 효도하기
     * 안마하기
     * 사격하기
     * 구보하기
     */
}



역할과 책임을 나누기 위해 여러개의 클래스로 변경했다. 이렇게 되면 각각의 역할과 책임만 가지면 되니 훨씬 깔끔하고 좋다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class BoyFriend {
    //키스하기
    //기념일 챙기기
}
 
class Son {
    //효도하기
    //안마하기
}
 
class Employee {
    //출근하기
    //아부하기
}
 
class Soldier {
    //사격하기
    //구보하기
}



SRP를 지키지 않는 사례 


속성이 SRP를 지키지 않은 경우


1
2
3
class Man {
    String military_serial_number;
}



남자는 무조건 군대를 간다. 여자는 가지 않는다 라고 가정을 했을 때 사람 클래스가 정의되어 있다. 이렇게 되면 남자 클래스는 군대를 가기 때문에 괜찮지만, 여자 클래스일 경우에는 문제의 소지가 있다. 문제 해결을 위해 남자 클래스와 여자 클래스를 분할 하고 공통인 부분이 있다면 사람 클래스를 상속받아서 사용하고 각각 차이점을 구현하면 된다.

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


메서드가 단일 책임 원칙을 지키지 않은 경우


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Man {
    private boolean sex;
    
    public void setSex(boolean sex) {
    
        this.sex = sex;
    }
    
    public void pee() {
        
        if(sex == true) {
            System.out.println("서서 봅니다.");
        } else {
            System.out.println("앉아서 봅니다.");
        }
    }
}



위의 예제는 남자, 여자에 따라서 소변을 보는 행위를 구현하고 있다. 하지만 boolean값에 따라서 수컷 강아지의 행위와 암컷 강아지의 행위를 모두 구현하려고 하기에 단일 책임(행위) 원칙을 위배하고 있다. 메서드가 단일 책임 원칙을 지키지 않았을 경우 나타나는 대표적인 예가 분기 처리 이다.


문제 해결을 하려면 아래와 같이 공통기능 추상 클래스를 만들고 상속 받아서 사용하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
abstract class Man {
    abstract void pee();
}
 
class Male extends Man{
 
    @Override
    void pee() {
        // TODO Auto-generated method stub
        System.out.println("서서 봅니다.");
    }
}
 
class Female extends Man{
    
    @Override
    void pee() {
        // TODO Auto-generated method stub
        System.out.println("앉아서 봅니다.");
    }
}




출처 - 스프링 입문을 위한 자바 객체 지향의 원리와 이해