본문 바로가기

Language/C++ Design Pattern

ISP 원칙

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

(C++ 소프트웨어 디자인 책 정리)


사용하지 않는 메서드에 클라이언트가 의존하도록 강요해서는 안 된다.

 

앞서 SRP 법칙의 document  예제를 다시 보자.

이번에는  document 클래스의 개별 함수가 아닌 전체 인터페이스에 집중한다.

class Document
{
  public:
  // ...
  virtual ~Document() = default;
  
  virtual void exportToJSON( /*...*/ ) const = 0;
  virtual void serialize( ByteStream bs, /*...*/) const = 0;
  //...
};

 

Document에는  JSON 내보내기와 직렬화를 모두 처리하는 파생클래스가 필요하다, 문서 관점에서는 이는 합리적일 수 있지만, 불행히도 다른 결함을 일으킨다.

다음 사용자 코드를 보자.

void exportDocument( Document const &doc)
{
  // ...
  doc.exportToJSON( /* ... */);
  // ...
 }

 

exportDocument() 함수는 오로지 주어진 문서를 JSON으로 내보내는 데만 관심이 있다.

즉, exportDocument() 함수는 문서 직렬화나 Document가 제공해야 하는 다른 기능과 관련이 없다. 그런데도 Document 인터페이스 정의 결과로 많은 직교적 관심사를 함께 결합하기 때문에 exportDocument() 함수는 JSON 내보내기보다 더 많은 것에 의존하다.

 

ISP는 인터페이스를 분리해 관심사를 분리할 것을 조언한다. 아래 예제에서는 JSON 내보내기와 직렬화라는 두 직교적 관심사를 나타내는 별도의 인터페이스가 둘 있어야 한다.

 

class JSONExportable
{
  public:
  // ...
  virtual ~JSONExportable() = default;
  
  virtual void exportToJSON( /* ... */ ) const = 0;
  // ...
};

class Serializable
{
  public:
  // ...
  virtual ~Serializable() = default;
  
  virtual void serialize( ByteStream& bs, /* ... */) const = 0;
  // ...
  
 };
 
 class Document
   : public JSONExportable
   , public Serializable
{
  public:
  // ...
  
};

 

이 분리로 Document 클래스가 쓸모 없어지지는 않는다. 반대로 Document 클래스는 여전히 모든 문서에 대한 요구사항을 나타낸다. 하지만 이제 이런 관심사 분리를 통해 실제 필요한 긴으 집합으로 의존성을 최소화할 수 있다.

void exportDocument( JSONExportable const& exportable)
{
  // ...
  exportable.exportToJSON( /* ... */);
  // ...
}

 

이 형식에서는 분리한 JSONExportable 인터페이스만 의존함으로써 epxortDocument() 함수는 더 이상 직렬화 기능에 의존하지 않으므로 ByteStream 클래스에 더 이상 의존하지 않는다. 따라서 인터페이스 분리가 결함을 줄이는데 도움이 됐다.

 

'Language > C++ Design Pattern' 카테고리의 다른 글

DIP 원칙  (0) 2025.01.30
LSP 원칙  (0) 2025.01.30
OCP 원칙  (0) 2025.01.29
SRP 원칙  (0) 2025.01.29