2012-09-01 3 views
0

C++에서 주기적 종속성 문제를 다루고 있습니다. 다음과 같이클래스 템플릿을 사용하는 C++ 순환 종속성 - 리팩토링하는 방법?

상황은 같습니다 LIBA가 libB에서 변환기 클래스를 사용하고 libB 변환 할 필요가 LIBA의 객체 유형에 대해 지금이 필요하기 때문에

libA.so: 
    - Body.cpp 
    - Header.cpp 
    - DataObject.cpp 
    - DataObject::read(boost::asio::streambuf* data) 
     { 
      boost::asio::streambuf data; 

      .... 

      body = (new DataConverter<Body>)->convert(&data); 
      header = (new DataConverter<Header>)->convert(&data); 
     } 

    libB.so: 
     - DataConverter.cpp 
      -> DataConverter<T> 
      -> T* DataConverter<T>::convert(boost::asio::streambuf* data) 

    libA.so <-> libB.so 

는 순환 종속성이 있습니다 - DataConverter :: convert는 Body 또는 Header 객체를 반환하기 때문에

전방 선언을 사용하여이 문제를 해결할 생각이었습니다. 그러나 저에게는 가장 깨끗한 해결책이 아닙니다. 모두 내 계획은 확장 가능한 DataConverter 솔루션을 제공하는 것이 었습니다.

여러분은 모범 사례로서 무엇을 제안합니까? 완전한 다른 디자인은, 세바스찬

+0

이 ... 그러나 달성하기 어렵고 파괴하기 쉬운 'convert'가'delete this'로 끝나지 않는 한, 그것은 겁에 질리게됩니다.) –

+0

그것은 다른 것보다 더 많은 의사 코드입니다. –

답변

1

당신은 서로 구현 (파생 클래스) 인터페이스를 정의하는 추상 기본 클래스를 생성하고 숨길 수도

최저

:)를 환영합니다.

+0

Ok - 실제로 지정된 구현 된 타겟 형식에 대한 구체적인 구현을 반환하는 AbstractConverter Factory를 정의하는 것은 어떻습니까? 하지만 어떻게하면 내 의존성 문제를 해결할 수 있을까요? –

+1

변환기에 필요한 모든 메서드 (추상)를 포함하는 추상 클래스를 정의합니다. 헤더 파일에서 그렇게 할 수 있습니다. 이 헤더를 liba.so와 libb.so의 소스에 모두 포함하십시오. libb의 변환기는 추상 클래스에서 (사실상, 아마) 파생됩니다. libb에는 변환기를 반환하는 두 개의 팩토리 메서드가 들어 있으며이 팩터 리 메서드는 liba의 extern으로 선언됩니다. 따라서 libb는 liba에 대해 알고 있지만 liba는 libb에 대해 알지 못합니다. – JohnB

8

클래스 템플릿 DataConverter이 필요하면 컴파일 된 라이브러리의 일부가 될 수 없습니다. 포함 파일을 통해 사용할 수 있어야합니다. DataConverter 코드를 머리글에 넣었 으면 libAlibB 모두에서 사용되며 주기적 종속성이 사라집니다.

3

디자인에 결함이있는 것 같습니다. A와 B라는 두 라이브러리가 서로 종속되어 있다면, 항상 함께 제공되어야 함을 의미합니다. 항상 함께 배송해야하는 경우 논리적으로 동일한 인터페이스에 속하게됩니다. 사실, 하나의 라이브러리 만 있습니다.

이 최선의 해결책이 될 것입니다 무엇을 말할 수있는 충분한 정보가 아니라, 여기에 몇 가지 팁입니다

  1. 이 라이브러리를 병합합니다.
  2. 하나의 라이브러리를 다른 라이브러리에 종속 시키십시오 (예 : DataConverter를 libA로 이동).
  3. 이 두 가지에 따라 유틸리티 라이브러리를 만듭니다.
  4. 템플릿 또는 가상 클래스를 사용하여 libB에 적절한 인터페이스를 만들고 libB를 libB에 종속되게 만듭니다. 후자 (가상 클래스)는 동적으로 링크 된 라이브러리에서 더 나은 선택 일 가능성이 큽니다.
1

일부 대안 : 컴파일시에 적절한 종류의 libA.so에 instantianted됩니다 완전히 일반적인 구현 등

  1. DataConverter. 이것은 전형적인 C++ - ish 솔루션이었습니다. LIBA (또는 다른)에서 "convertable"유형 존은 말하기에 의해 제안 된, DataConverter의 완전 플릿 구현

  2. 종속성 반전을 사용하는 것입니다 일부 Convertable 개념을 충족해야합니다. 기본적으로 동일한 목표를 달성하지만 인터페이스, 구현 및 런타임에 등록/해결이 가능합니다. 할 일이 많지만 확장 성이 뛰어나고 ABI는 성취 가능하며 도서관 등으로 배치 가능합니다 ...

  3. Boost.Serialization과 같은 두 종류의 똑똑한 조합입니다. 당신이 거의 확실`없음`new`와 DataConverter () .convert (데이터)`(원하는 -이

    나에게 메모리 누수과 같은