오늘은 oop와 관련된 이야기를 해볼 예정이다. oop의 구성요소를 살펴볼 것은 아니고 원칙들을 살펴 볼건데 그중에서 오늘은 인터페이스 분리 원칙(ISP) 에 대해서 살펴보도록 하자. 간단하게만 살펴볼 예정이니.. 사실 필자가 이해한 정도만..
그 전에 oop의 어떤 원칙들이 있나 보자. oop에는 5가지 원칙들이 있다. 위에서도 적었지만 인터페이스 분리 원칙 (ISP), 단일책임원칙 (SRP), 개방 폐쇄의 원칙 (OCP), 리스코프의 치환원칙 (LSP), 의존성 역전 원칙 (DIP) 등 이 있다.
뭔가 심오한 단어인듯만 같다. 여러가지 원칙들이 있지만 오늘은 인터페이스 분리 원칙 (ISP)에서만 다뤄보자. 나머지는 다음 기회에 포스팅해 보도록 하고(쓸려나 모르겠지만).. 솔직히 이해하기가 이게 제일 쉬워서 먼저 쓰는거 뿐이다.

인터페이스 분리 원칙

일단 정의를 살펴보도록 하자. 위키에 보면 다음과 같이 설명하고 있다.

The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use

대충 해석해보면 다음과 같다.

인터페이스 분리 원칙이란 클라이언트가 사용하지 않는 메서드에 의존하지 않아야 한다고 한다.

이게 무슨말인가.. 정의를 봐도 모르겠구나..
아무튼 간단하게 말하자면 자신과 관련없는 메서드들은 구현하지 말아야 한다는 뜻이다.

말보단 코드가 낫기 때문에 코드로 살펴보자.
음.. 예제는 필자가 노트북을 살려고 고민중이니 노트북으로 예를 들어보자. (맥북에어로는 개발이 쉽지 않아..)

public interface MacPro {

  void display();

  void keyboard();

  void touch();
}

맥프로에는 디스플레이, 키보드, 터치바등이 있다. 물론 여러가지가 더 있겠지만 중요한건 그게 아니므로..
그리고 이번에 나온 MacPro 2016년형을 구현해보자!.

public class MacPro2016 implements MacPro {
  @Override
  public void display() {
    System.out.println("mac pro2016 display");
  }

  @Override
  public void keyboard() {
    System.out.println("mac pro2016 keyboard");
  }

  @Override
  public void touch() {
    System.out.println("mac pro2016 touch bar");
  }
}

이번에 나온 맥프로를 구현했다. 이번에 나온 맥프로에는 touch bar 도 존재한다. 그닥 잘모르겠다 좋은지.. 그래서 2015년형을 사려고 하는데.. 그래도 비싸..ㅜㅜ

아무튼 내가 갖고 싶은 mac pro를 구현해봤다. 음.. 근데 필자가 갖고 싶은 맥북프로는 2015년형이다. 그래서 2015년형 맥북도 구현했다.

public class MacPro2015 implements MacPro {
  @Override
  public void display() {
    System.out.println("mac pro2015 display");
  }

  @Override
  public void keyboard() {
    System.out.println("mac pro2015 keyboard");
  }

  @Override
  public void touch() {
    // ?? 
  }
}

하하 드디어 내가 갖고 싶은 맥북프로가 완성되었다. 잉? 근데 이상하다. 2015년형에는 터치바가 없다. 터치바는 이번에 나온 신형부터 있으니 말이다. 그래서 구현을 하지 않았다. 뭔가 느낌이 왔다면 그게 바로 정답이다.

이게 바로 아까 위에서 이야기 했던 클라이언트가 사용하지 않는 메서드에 의존하지 않아야 한다고 한다 이 이야기이다. 이제야 조금 이해가 되지 않나?

그럼 어떻게 해야 될까? 한번 인터페이스 분리 원칙에 따라 수정해보도록 하자!!
말그대로 인터페이스를 분리하면 된다.

public interface MacPro {

  void display();

  void keyboard();

}

기본적인 맥프로에는 display 와 keyboard가 존재한다. 모든 맥프로에는 display와 keyboard가 있으니 MacPro 인터페이스에는 display, keyboard만 정의해주자.

public interface MacProTouch {

  void touch();
}

그리고 나서 MacProTouch라는 인터페이스를 만들어서 touch 라는 메서드를 정의하자. 한번 다시 구현해 보도록 하자!

public class MacPro2016 implements MacPro, MacProTouch {
  @Override
  public void display() {
    System.out.println("mac pro2016 display");
  }

  @Override
  public void keyboard() {
    System.out.println("mac pro2016 keyboard");
  }

  @Override
  public void touch() {
    System.out.println("mac pro2016 touch bar");
  }
}

위는 이번에 나온 맥프로를 구현했다. 기본이 되는 MacPro와 추가된 MacProTouch 인터페이스를 구현하면 끝이다. 이번엔 2015년형 맥북 프로를 구현해보자.

public class MacPro2015 implements MacPro {
  @Override
  public void display() {
    System.out.println("mac pro2015 display");
  }

  @Override
  public void keyboard() {
    System.out.println("mac pro2015 keyboard");
  }
}

간단하다. 2015년형에는 터치바가 없으니 MacPro만 구현해주면 된다. 참 쉽다? 말은 청산유수다..

인터페이스를 각각 쪼개서 사용하는 인터페이스만 구현해주면 되는 것이다. 그렇지만 너무 쪼개다 보면 원하지 않게 인터페이스가 어마어마하게 많아 질 수도 있다. 그럼 어떻게하냐? 글쎄다.. 필자도 모르겠다. 한 클래스가 적당한 책임을 쥔 상태에서 나누는게 좋을 듯하다. 이건 경험에서 나올 수 있으니 연습을 많이 해야 할 듯 싶다.

인터페이스를 잘 설계하는 건 쉽지 않다. 만약 인터페이스가 변경 된다면 구현한 모든 클래스들에게 영향을 주니 고민을 많이하고 설계를 해야 될 듯 싶다. 만약 인터페이스를 설계한다면 구현의 시간만큼 인터페이스를 설계하는데에도 시간을 많이 투자하자! 잘 설계된 인터페이스라면 상관없겠지만 잘 설계되지 않았던 인터페이스 였다면 그 보다 시간을 뺏길지도 모르니..

오늘은 이렇게 인터페이스 분리 원칙(ISP)에 대해서 알아봤다. oop는 어렵단 말이야.. 다음 시간에는 단일책임원칙(SRP) 에 대해서 살펴보도록 하자..
SRP.. 이건 또 무엇인가..