Developer Log
  • Wiki
  • Books
    • 리눅스 시스템 프로그래밍
      • 핵심 개념 소개
        • 시스템 프로그래밍
        • API와 ABI
        • 리눅스 프로그래밍의 개념
          • 파일과 파일시스템
          • 프로세스
          • 사용자와 그룹
          • 권한
          • 시그널
          • 프로세스간 통신
          • 에러 처리
    • 데이터 베이스 첫걸음
      • 데이터베이스란
        • 데이터베이스의 역할을 생각해 보자
          • 우리와 데이터베이스의 관계
          • 데이터베이스의 기본 기능
          • 데이터베이스 종류
      • 관계형 데이터베이스란
        • 대표적인 DBMS를 알아보자
          • 관계형 데이터베이스란
          • SQL 기초 지식
          • 관계형 데이터베이스를 다루기 위한 사전 지식
      • 데이터베이스에 얽힌 돈 이야기
        • 초기비용과 운영비용을 생각하자
      • 데이터베이스와 아키텍처 구성
        • 다중화에 대해 생각해보자
          • 아키텍처란
          • 데이터베이스의 아키텍처
            • 역사와 개요
              • Stand-alone
              • 클라이언트/서버
              • Web 3계층
            • 가용성과 확장성의 확보
          • DB 서버의 다중화
            • 클러스터링
            • 리플리케이션
          • 성능을 추구하기 위한 다중화 - Shared Nothing
          • 적합한 아키텍처를 설계하기 위해
      • DBMS를 조작할 때 필요한 기본 지식
        • MySQL 설치해보자
        • MySQL과 커넥션 만들기, 데이터베이스에 전화걸기
        • SQL과 관리 명령의 차이
        • 관계형 데이터베이스의 계층
      • SQL 문의 기본
        • SELECT 문으로 테이블 내용을 살펴보자
        • SELECT 문을 응용해보자
        • 데이터를 갱신, 삽입, 제거해보자
        • 뷰를 작성하고 복수 테이블에서 선택해보자
      • 트랜잭션과 동시성 제어
      • 테이블 설계의 기초
      • 백업과 복구
      • 성능을 생각하자
    • 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴
      • 객체 지향
        • 들어가기
        • 객체 지향
        • 다형성과 추상 타입
        • 재사용: 상속보단 조립
      • 설계 원칙 / DI와 서비스 로케이터
        • 설계 원칙: SOLID
          • 단일 책임 원칙(Single Responsibility Principle)
          • 개방 폐쇄 원칙(Open - Closed Principle)
          • 리스코프 치환 원칙(Liskov Substitution Principle)
          • 인터페이스 분리 원칙(Interface Segregation Principle)
          • 의존 역전 원칙(Dependency Inversion Principle)
          • SOLID 정리
        • DI(Dependency Injection)와 서비스 로케이터
      • 주요 디자인 패턴
        • 디지인 패턴이란?
        • 전략(Strategy) 패턴
        • 템플릿 메서드(Template Method) 패턴
        • 상태(State) 패턴
        • 데코레이터(Decorator) 패턴
        • 프록시(Proxy) 패턴
        • 어댑터(Adapter) 패턴
        • 옵저버(Observer) 패턴
        • 미디에이터(Mediator) 패턴
        • 파사드(Facade) 패턴
        • 컴포지트(Composite) 패턴
        • 널(Null) 객체 패턴
        • 팩토리 메서드 패턴
        • 커맨드 패턴
        • 추상 팩토리 패턴
    • 테스트 주도 개발
      • 1부
        • 다중 통화를 지원하는 Money 객체
        • 타락한 객체
        • 모두를 위한 평등
        • 프라이버시
        • 솔직히 말하자면
        • 돌아온 '모두를 위한 평등'
        • 사과와 오렌지
Powered by GitBook
On this page
  • 인터페이스 변경과 그 영향
  • 인터페이스 분리 원칙
  • 인터페이스 분리 원칙은 클라이언트에 대한 것

Was this helpful?

  1. Books
  2. 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴
  3. 설계 원칙 / DI와 서비스 로케이터
  4. 설계 원칙: SOLID

인터페이스 분리 원칙(Interface Segregation Principle)

Previous리스코프 치환 원칙(Liskov Substitution Principle)Next의존 역전 원칙(Dependency Inversion Principle)

Last updated 6 years ago

Was this helpful?

인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.

즉, 클라이언트는 자신이 사용하는 메서드에만 의존해야 한다.

인터페이스 변경과 그 영향

C++ 로 게시판 모듈을 개발한다고 해보자. ArticleService 클래스의 기능은 아래와 같다.

  • 게시글 작성

  • 게시글 목록

  • 게시글 삭제

기능에 대한 인터페이스 명세는 ArticleService.h 헤더 파일에 작성되고, 구현은 ArticleService.cpp 파일에 코딩될 것이다. 그리고 해당 클래스를 사용하는 코드는 #include를 이용해서 ArticleService.h 에 정의된 타입 정보를 이용해 코드를 작성할 것이다.

위의 그림과 같이 각 UI를 기준으로 개발 파트를 나누고 구현이 이루어 진다고 하면, 최종 실행 파일을 만들기 위해 다음과 같은 과정을 거치게 된다. 각각의 UI와 ArticleService.cpp을 컴파일한 결과 오브젝트 파일을 만들어 내고, 그 오브젝트 파일들을 링크하게 된다.

ArticleService 클래스의 목록 읽기 기능과 관련된 멤버 함수의 시그니처에 변경이 발생했다고 하자.

이 경우 ArticleService.h 헤더 파일과 ArticleService.cpp 파일에 변경을 반영한 뒤에 컴파일해서 ArticleService.o 오브젝트 파일을 생성할 것이다. 그리고 게시글 목록 기능에 변경이 발생했으므로, 게시글 목록 UI 소스를 변경한 뒤에 컴파일해서 게시글 목록 UI 오브젝트 파일을 생성할 것이다.

그러나 변경은 여기서 끝나지 않는다. ArticleService.h 파일이 변경되었기 때문에 이 헤더 파일을 사용하는 게시글 작성 UI와 게시글 삭제 UI의 소스 코드도 다시 컴파일해서 오브젝트 파일을 만들어 주어야 한다.

결국, 게시글 작성 UI와 게시글 삭제 UI와 상관없는 게시글 목록 기능에 변경이 발생했음에도 불구하고 소스 코드를 다시 컴파일한 것이다.

인터페이스 분리 원칙은 자신이 사용하는 메서드에만 의존해야 한다는 원칙인데, 앞서 C++ 개발한 게시글 관리 프로그램 예제는 인터페이스 분리 원칙을 위반했다.

인터페이스 분리 원칙

ArticleService 클래스는 게시글 목록/작성/삭제에 대한 모든 메서드를 제공하고 있으며, 각 UI 코드는 ArticleService.h 헤더 파일에 의존하고 있다.

이로 인해 ArticleService 클래스의 한 메서드의 시그니처 변경에 따라, ArticleService.h 헤더 파일을 사용하는 모든 코드는 재컴파일해야 하는 상황이 발생한 것이다.

따라서, 위와 같이 ArticleService 인터페이스를 각 클라이언트가 필요로 하는 인터페이스들로 분리함으로써, 각 클라이언트가 사용하지 않는 인터페이스에 변경이 발생하더라도 영향을 받지 않도록 만들어야 한다.

게시글 쓰기 UI는 ArticleWriterService 인터페이스에 의존하고 있다. 따라서 ArticleListService.h 인터페이스에 변경이 발생하더라도 게시글 목록 UI만 영향을 받을 뿐 게시글 쓰기 UI나 게시글 삭제 UI를 다시 컴파일하지 않아도 된다.

자바 언어를 사용하고 있다면 컴파일을 통해 .class 파일을 생성하면 될 뿐, 링크 과정을 수행하지 않는다. 실제 링크 과정은 자바 가상 머신(JVM)이 .class 파일을 로딩하는 과정에서 동적으로 발생되기 때문에 개발자가 각 클래스 파일들을 연결하는 링크 과정을 직접해 줄 필요가 없는 것이다. 따라서 자바 언어에서는 위의 문제가 발생하진 않는다.

용도에 맞게 인터페이스를 분리하는 것은 단일 책임 원칙과도 연결된다.

단일 책임 원칙에서 봤듯이 하나의 타입에 여러 기능이 섞여 있을 경우, 한 기능의 변화로 인해 다른 기능이 영향을 받을 가능성이 높아진다.

따라서, 클라이언트 입장에서 사용하는 기능만 제공하도록 인터페이스 분리함으로써 한 기능에 대한 변경의 여파을 최소화할 수 있게 된다.

또한, 단일 책임 원칙이 잘 지켜질 때 인터페이스와 콘크리트 클래스의 재사용 가능성이 높일 수 있으므로, 인터페이스 분리 원칙은 결국 인터페이스와 콘크리트 클래스의 재사용성을 높여 주는 효과도 갖는다.

인터페이스 분리 원칙은 클라이언트에 대한 것

인터페이스 분리 원칙은 클라이언트 입장에서 인터페이스를 분리하라는 원칙이다.

'의존의 양면성'을 통해, ArticleService 인터페이스의 변화가 게시글 목록 UI에 영향을 주지만, 반대로 게시글 목록 UI의 요구로 인해 ArticleService 인터페이스가 변경될 수 있다.

의존의 양면성

A가 B를 의존할 경우,

B의 변화로 인해 A가 변경되지만, 반대로 A의 요구에 의해 B가 변경될 수 있다.

이는 인터페이스 분리의 기준이 클라이언트가 된다는 것을 알 수 있다.

각 클라이언트가 사용하는 기능을 중심으로 인터페이스를 분리함으로써, 클라이언트로 부터 발생하는 인터페이스 변경 요의 여파가 다른 클라이언트에 미치는 영향을 최소화할 수 있게 된다.