인터페이스 분리 원칙이란?

SOLID 원칙 중 인터페이스 분리 원칙(ISP: Interface Segregation Principle)은 클라이언트는 자신이 사용하지 않는 메서드에 의존하면 안된다는 개념을 기반으로 합니다.
즉, 하나의 거대한 인터페이스를 여러 개의 작은 인터페이스로 나누어, 특정 기능만 사용할 수 있다라는 개념인데요

그렇다면 인터페이스 분리 원칙이 왜 필요한가? 라는 의문을 가질 수 있습니다.

  1. 불필요한 메서드 구현을 방지하여 불필요한 의존성을 줄일 수 있습니다.
  2. 역할별 인터페이스를 분리하여 확장성과 유지보수성을 높일 수 있습니다.
  3. 특정 기능만 필요로 하는 클래스가 사용하지 않는 메서드를 강제로 구현하는 문제를 해결할 수 있습니다.

그럼 예제를 통해서 알아보겠습니다.

1. 위반 예시

다음과 같은 사용자 서비스가 존재한다고 했을 때, 다음과 같은 문제점이 있습니다.

  1. 일반 사용자(User)는 deleteUser(), createAdmin(), deleteAdmin()을 사용할 필요가 없습니다.
  2. UserService가 불필요하게 커지면서, 특정 역할에 대해서는 필요 없는 기능을 구현해야 하는 문제가 발생합니다.
  3. 일반 유저도 deleteAdmin() 같은 메서드를 강제로 구현 해야하는 문제점이죠.
    • 이렇게 구현할경우, NormalUserServiceImpl과 같은 서비스 구현체에 UserService를 상속받아 메서드를 구현할 경우, Null 또는 Exception 발생 시, 런타임에서 오류를 캐치할 수 없고, 예상치 못한 오류가 발생할 수 있는 것이죠

2. 해결 예시

code1

위와 같이 공통적으로 사용하는 함수에 대해서 정의하는 인터페이스를 생성한 후

각 역할에서 사용하는 함수가 정의된 인터페이스를 별도로 생성해줍니다.

code2 code3

이렇게 별도로 인터페이스를 생성하고 구현체를 아래와 같이 적용하면

2-1. 일반 사용자 구현체

code4

일반 사용자는 viewProfile()과 updateProfile()에 맞는 기능만 수행할 수 있으며

2-2. 관리자 구현체

code5

2-3. 슈퍼 관리자 구현체

code6

관리자와 슈퍼관리자의 경우에도 역할에 맞는 함수만 갖는 클래스를 생성할 수 있습니다.

이렇게 작성하면 인터페이스를 역할별로 분리가 가능해지고 필요한 기능만을 구현 가능하고, 새로운 역할 추가 시, 기존 코드 수정 없이 확장이 가능해집니다. 이렇게 되면 코드의 유지보수성이 향상됩니다.