밤에 쓴 코드

OOP ) ISP- 인터페이스 분리 법칙 (Interface segregation principle) 본문

OOP

OOP ) ISP- 인터페이스 분리 법칙 (Interface segregation principle)

붱이🦉 2019. 5. 18. 21:28

ISP- 인터페이스 분리 법칙 (Interface segregation principle)

클래스 내에서 사용하지 않는 인터페이스는 구현하지 말아야 한다.

DIP 에서 만들어진 고양이가 잘 이동하고 있다 .
DIP - 의존관계 역전법칙(Dependency inversion Principle)

강아지도 추가해서 , 이쁘게 움직이게 만들어 주었다.

그런데 어느날 '달팽이'가 필요해졌다.

struct 달팽이(){
    let 움직이기전략: 움직이는방법  // 구체적이지 않은 클래스에 의존

    func 이동하기(){
        움직이기전략.이동하다()
    }
  //DI - 의존성주입
    mutating func 움직이는방법바꾸기(_ 새로운움직이기전략:움직이는방법){
      self.움직이기전략 = 새로운움직이기전략
    }
}
struct 점프못하는느린움직임: 움직이는방법 {
    func 이동하다() {
         print("~")
    }

    func 점프하다() {
         ()
    }
}
let 🐌 = 달팽이(점프못하는느린움직임())

달팽이 는 안타깝게도 점프를 못하는 아이 이다.

그래서 점프를 못하는 움직임이 필요해졌다.

그과정에서 이전과 같이 움직이는방법 이라는 프로토콜을 채택했고 , 필요없는 점프하다 라는 메소드를 구현을 텅비게 하였다.

스크린샷 2019-05-18 오후 9 07 51

하지만 외부에서 달팽이는 점프하기를 할수있는 객체로 보고있다.

점프를 하게해보면 아무동작은 안하는 걸 알 수 있겠지만 , 그걸 실행해보기 전까진 알 수 없다.

이런 방법은 클래스의 응집도가 떨어뜨리게 된다 . 달팽이라는 아이는 달팽이와 관련된 동작과 상태로 가득가득해야하는데 . 쓸모없고, 관계도 없는 동작이 들어가게되면서 , 응집도가 낮아진 것이다.

왜 이런 일이 일어났을까?

하나의 프로토콜을 채택하는 순간 그에 부수적인 많은 것들을 다 강요 받기 때문이다.

패스트푸드점이 있다.

M 사 는 단품(🍔), 콜라(🥤), 감자튀김(🍟) , 세트(🍔🍟🥤) 이런 선택지가 있다.

L 사는 세트(🍔🍟🥤) 라는 단일 선택지가 있다.

세트를 먹기 위한 사람은 어디를 가던지 상관없지만, 감자튀김이나 콜라를 싫어하는 사람에게는 M사가 더 구미가 댕길 것이다.

// 나는 감자튀김을 싫어하기때문에 L사 안갈것같다.

감자튀김을 먹기싫어하는 사람은 세트를 사면서 , 쓸데없는 것을 얻게 된다.

이것에 대한 해결로는 M사 가 했듯이 , 각각을 분리해서 두고 , 합쳐서도 판매 한다면 , 필요한 것만 쏙쏙 쓸수도 있게 될 것이다.

이 방법으로 달팽이를 좀 더 달팽이 답게 바꿔보자.

protocol 점프하는방법 {
    func 점프하다()
}
protocol 이동하는방법 {
     func 이동하다()
}
typealias 움직이는방법 = 점프하는방법 & 이동하는방법

움직이는방법이동하는방법, 점프하는방법 으로 분리해 냈다.

struct 점프못하는느린움직임: 이동하는방법 {
    func 이동하다() {
        print("~")
    }
}

이렇게 분리하게 되니 쓸데없는 구현이 없는 움직임방법이 생겼다.

struct 달팽이 {
    var 이동방법: 이동하는방법

    func 이동하기(){
        이동방법.이동하다()
    }
    mutating func 움직이는방법바꾸기(_ 새로운이동방법:이동하는방법){
        self.이동방법 = 새로운이동방법
    }
}

그리고 달팽이도 온전히 달팽이 답게 움직일수 있게 되었다.

DIP과정에서 추상적인 부분을 분리해 내면서 , 의도하지는 않았지만 , Interface 가 커지는 것을 경험했을 것이다.

하지만 Interface가 크다는 것은 한번에 지켜야 할 약속이 너무 많아진 다는 것이다 .

커진 인터페이스에서 적당한 동작으로 구분해내야한다.

한 인터페이스당 하나만 메소드를 구현하면 무조건 좋을거같은데? 그러면 , 그걸 조합해 나가면 다 되지 않을까?

꼭 작아야하는 건 아니다. 적당히 작아야한다.

다시 햄버거 가게로 가보자

M 사 는 단품(🍔), 콜라(🥤), 감자튀김(🍟) , 세트(🍔🍟🥤) , 추가로 쿠키(🍪) 를 팔게 되었다.

쿠키는 특별히 100원 에 판매한다 .

대신 세트를 구매한 사람에 한해서 판매한다.

이런 경우 , 쿠키를 사기위해서는 다른 100원을 내는 약속 + 세트를 구매한다는 약속

이 두가지가 강요되어진다 .

이런 경우에는 묶어둠으로써 , 약속을 강제적으로 지키게 만들어야할 필요가 있는 것이다.

이상 SOLID 원칙 이었습니다.

Comments