오늘도 더 나은 코드를 작성하였습니까?

디자인 패턴의 원칙 (Single responsibility) 본문

디자인패턴

디자인 패턴의 원칙 (Single responsibility)

hik14 2021. 12. 24. 16:32

디자인패턴

- 개발을 하다 마주치는 문제를 해결하기 위한 방법들의 모음.

- 코드를 읽기 쉽고 재사용하기 쉽게.

- 디자인 패턴을 적용을 하려고 패턴을 문제에 맞추면 안된다.

- 2개 이상 패턴이 혼용되어 적용되는 경우도 있다.

- 단순히 Functional Programming으로 더 읽기 쉬운 경우도 있다.

 

Single responsibility(단일 책임의 원칙)

객체 지향 프로그래밍에서 single responsibility principle이란 모든 함수/클래스/모듈는 하나의 책임만 가지며,  그 책임을 완전히 캡슐화해야 함을 일컫는다. 함수/클래스/모듈가 제공하는 모든 기능은 이 책임과 주의 깊게 부합해야 한다.

 

 

1.  하나가 많은 책임을 지고 있는 경우

fun multiplicationTable(start: Int, end: Int) {

    if (start < 2) {
        println("error: 2단 이상부터 출력가능 합니다")
        return
    }
    
    if (start > end) {
        println("error: 시작하는 단은 마지막 단보다 작거나 같아야합니다")
        return
    }

    for (dan in start..end) {
        println("start: $dan dan")
        for (idx in 1..9) {
            println("$idx x $dan = ${idx * dan}")
        }
    }
}

구구단을 출력하는 함수가 있다. 

위 함수는 시작 단과 끝나는 단을 입력받아 출력하며,  옳바르지 못한 입력에있어 에러 메세지를 출력한다. 정상적인 입력값이 들어오면 원하는 범위의 구구단을 출력해준다.

 

위 함수는 최소한 2가지 작업(책임)을 하고 있는데,

1. 정상적인 입력값의 검사,

2. 각 정해진 단의 구구단의 생성

 

아래와 같이 작업과 그에 따른 책임을 분산시킬 수 있다.

fun singleMultiplicationTable(dan: Int) {
    for (idx in 1..9) {
        println("$idx x $dan = ${idx * dan}")
    }
}

fun checkRange(start: Int, end: Int): Boolean {
    if (start < 2) {
        println("error: 2단 이상부터 출력가능 합니다")
        return false
    }
    if (start > end) {
        println("error: 시작하는 단은 마지막 단보다 작거나 같아야합니다")
        return false
    }
    return true
}

fun multiplicationTable(start: Int, end: Int) {

    if (!checkRange(start, end))
        return
    else
        for (dan in start..end) {
            println("start: $dan dan")
            singleMultiplicationTable(dan)
        }
}

2. 캡슐화 되지 못할 책임을 지고있는 경우

class Dog(val name: String, val age: Int){

    fun eat(food: String) = println("냠냠..$food")

    fun cry() = println("멍멍, 멍멍")

    fun sleep() = println("zzz...zz")

    fun running() = println("헥헥헥.. 멍멍")

    fun takeWalkInPark(){
        // TODO
    }
}

 위 클래스는 간단하게 강아지를 모델링하였다.

하지만 위의 함수중에 takeWalkInPark(공원 산책 시키기)는 강아지가 할수 없는 작업이기 때문에 매우 이질적이다.

takeWalkInPark는 강아지의 주인이 해야하는 일이기 때문에 아래와 같이 수정을 해야 책임에대한 소재가 옳바르다.

class Dog(val name: String, val age: Int){

    fun eat(food: String) = println("냠냠..$food")

    fun cry() = println("멍멍, 멍멍")

    fun sleep() = println("zzz...zz")

    fun running() = println("헥헥헥.. 멍멍")
}

class Person(val name: String, val age: Int){

    fun takeWalkInPark(dog: Dog){
        dog.running()
        dog.running()
        dog.eat("개껌")
    }
}

'디자인패턴' 카테고리의 다른 글

전략패턴(Strategy Pattern)  (0) 2022.07.11
Dependency Inversion Principle  (0) 2021.12.28
Interface Segregation  (0) 2021.12.28
리스코프 치환법칙(Liskov Substitution)  (0) 2021.12.28
Open-Closed Principle  (0) 2021.12.24