이번 포스트에서는 SOLID 원칙의 네 번째인 ISP 에 대해서 예시와 함께 다뤄보려고 한다.
ISP (Interface Segregation Principle)
ISP 는 Interface Segregation Principle 의 약어로, 인터페이스 분리 원칙을 의미한다. ISP 의 개념은 다음과 같다.
Clients should not be forced to depend upon interfaces that they do not use.
클라이언트는 사용하지 않는 인터페이스에 의존을 강요당해선 안된다.
좀 더 풀어서 설명하면, 클라이언트를 기준으로 인터페이스를 분리하라는 뜻이다. 클라이언트는 그 인터페이스를 사용하는 프로그래밍 요소인데, 보통 인터페이스를 구현하는 클래스를 의미한다.
먼저 예시를 통해 ISP 가 지켜지지 않으면 어떤 문제가 생기는지 살펴보자.
Fig1 에서는 복합기 인터페이스를 만들고, 그 후에 컬러 복합기, 프린터 클래스, 복사기 클래스, 팩스 클래스를 구현했다. 컬러 복합기의 경우에는 문제가 없지만, 프린터는 프린트만 하면 되는데 copy() 메서드와 fax() 메서드를 구현해야 한다. 복사기와 팩스도 마찬가지로 불필요한 메서드를 구현해야 한다.
만약 복합기의 copy() 메서드의 시그니처(메서드명, 파라미터의 순서, 타입, 개수)가 변경된다면 Printer 클래스와 Fax 클래스는 copy 와 관련이 없지만 불필요한 메서드 변경이 필요하고, 이는 유지 및 보수가 힘들어진다고 볼 수 있다. 그러면 더 분리된 클라이언트를 기준으로 다시 설계해보자.
이번에는 프린트를 하는 인터페이스, 복사를 하는 인터페이스, 팩스를 하는 인터페이스를 분리하고 복합기 클래스는 세 개의 인터페이스를 구현하도록 만들었다. 각 인터페이스를 구현하는 클래스도 분리되어, 각 인터페이스 변경 시 해당 인터페이스를 구현하는 클래스에서만 변경하면 된다.
ISP 로 얻을 수 있는 이점은 인터페이스가 잘 분리되어 있으면 인터페이스의 재사용성을 높이고, 해당 인터페이스를 구현하는 Concrete 클래스의 관리가 쉬워진다.
ISP 의 핵심
SRP 는 클래스를 책임 단위로 분리하라는 원칙이었다. ISP 는 클라이언트를 기준으로 인터페이스를 분리하라는 원칙인데, 분리라는 공통점이 있지만 차이점도 있다. 인터페이스는 구현부가 없는 완벽한 추상 클래스를 의미하고(기본 구현은 제외하고 생각하자), 인터페이스 자체를 인스턴스화하는 것이 불가능하기 때문에 다음과 같은 특징이 있다.
- 구현부가 없는 완벽한 추상화는 이를 구현할 클래스들의 기본 구현이 없는 공통된 성질이다.
- 인터페이스를 재사용하여 Concrete 클래스를 구현하므로써 추상 메서드 구현을 컴파일 타임에 빠뜨리지 않는 것이 목적이다.
위와 같은 특징을 갖는 상황에서 인터페이스를 설계할 때, ISP 를 지키려면 클라이언트의 구분에 기준이 필요하다. 그것은 인터페이스의 메서드의 분리 기준과 같아진다. Fig1 에서 Printer, Copier, Fax 각각의 구체 클래스가 전혀 필요하지 않는 생각과 기획을 갖고 있다면, print(), copy(), fax() 의 메서드의 분리가 필요없는 것이다. 이 경우 오히려 Printer, Copier, Fax 인터페이스를 분리하는 것은 더 복잡한 설계가 된다.
즉, ISP 를 지키려면 인터페이스의 메서드들이 분리되어야 하는가를 고민해야 하고, 이 때 일부의 메서드만을 필요로 하는 클래스가 필요하다면 인터페이스를 분리하여 설계해야 한다는 것이다.
SOLID 의 다른 원칙 바로가기
Reference
- 최범균, 2014, 객체지향과 디자인 패턴, 인투북스
- [Wikipedia] “SOLID” — https://en.wikipedia.org/wiki/SOLID
- [위키백과] “SOLID (객체 지향 설계)” — https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)
- [TheUglyDuckling] “인터페이스 분리 원칙(ISP — Interface Segregation Principle)” — https://velog.io/@y_dragonrise/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EB%B6%84%EB%A6%AC-%EC%9B%90%EC%B9%99ISP-Interface-Segregation-Principle