2010-04-04 4 views
3

저는 Modern C++ Design 서적을 읽지는 않았지만 재미있는 템플릿을 통한 행동 주입 아이디어를 발견했습니다. 나는 지금 그것을 직접 적용하려고 노력 중이다.정책 기반 디자인 질문 적용

나는 정책으로 주입 될 수 있다고 생각되는 로거를 가진 클래스가 있습니다. ,

이제 퀘스트가
// basic_logger.hpp 
template<class String> 
class basic_logger 
{ 
public: 
    typedef String string_type; 

    void log(const string_type & s) { ... } 
}; 
typedef basic_logger<std::string> logger; 
typedef basic_logger<std::wstring> wlogger; 

// reader.hpp 
template<class Logger = logger> 
class reader 
{ 
public: 
    typedef Logger logger_type; 

    void read() 
    { 
     _logger.log("Reading..."); 
    } 

private: 
    logger_type _logger; 
}; 

리더가 상기와 같은 인자로 이력을해야 로거는 표준 : 문자열 또는 성병 :: wstring의 그 정책에 따라 취하는 로그() 메소드를 갖는다 또는 문자열을 취한 다음 인스턴스 변수로 basic_logger를 인스턴스화해야합니까? 좋아요 :

template<class String> 
class reader 
{ 
public: 
    typedef String string_type; 
    typedef basic_logger<string_type> logger_type; 

    // ... 

private: 
    logger_type _logger; 
}; 

올바른 방법은 무엇입니까?

+1

제발, 사물의 양은 적습니다. 이것은 C++입니다. –

+0

나는 자바에서 조금 손상되었다는 것을 안다 (나는 주로 그것에 관해 작업하지만 큰 팬이 아니다). 행동과 상태는 여전히 어떤 식 으로든 주입되어야합니다 (C++, Ruby 등). C++을 사용하면 부스트 (Boost)에서 알 수있는 것부터 정책 기반 디자인을 사용할 수 있습니다. 나는 그저 머리를 감싸려고 노력하고있다. – Arthur

+1

사실 Alexandrescu가 이와 비슷한 예를 보여 주므로 실제로 Modern C++ Design을 읽는 것이 가장 도움이 될 것입니다. –

답변

2

실제로 정책 클래스를 사용하려면 정책이 템플릿 매개 변수 여야합니다. 한 가지 예는 상속을 사용하여 빈 기본 클래스 최적화를 사용하고 클래스의 공용 인터페이스에 쉽게 추가 할 수있게 해주는 MC++ D의 정책과 다르게 구현되었지만 basic_string에 대한 char_traits 매개 변수입니다 (훨씬 더 나은 방법으로 각 가능한 방법을 래핑, 다시 MC++ D를 읽으십시오). 기본값 :

template<class String, class Logger=basic_logger<String> > 
struct reader : Logger { 
    void read() { 
    this->log("Reading..."); 
    } 
}; 
+0

나는 Alexandrescu의 책을 읽어야한다고 말하는 것이 맞다고 생각한다. 이 책의 몇 가지 예를 살펴 보았지만 책이 없으면 예를 문맥에 넣기가 약간 어렵습니다. 예를 들어 빈 기본 클래스 최적화에 대해 알지 못했습니다. 어쨌든이 질문에 대한 답변입니다. 감사! – Arthur

1

독자가 로거 유형 또는 읽는 유형에 대해 매개 변수를 지정해야합니까? 이것이 질문이라면, 그 대답은 명백하다고 생각했을 것입니다.

이 질문의 문제점 IMHO는 String이나 Logger가 실제로 정책이 아닙니다. 정책은 컴파일 타임에 로그 작성기와 같은 기능이 로깅에 어떻게 적용되어야 하는지를 알려줍니다. 코드는 판독기에 일종의 로거를 제공하기 만합니다.이 코드는 상속을 사용하여 런타임에 똑같이 수행 될 수 있습니다.

+0

당신 말이 맞아요. 이 경우 로거는 런타임에 설정하는 것이 좋습니다. 그러나 로거를 로깅 정책으로 보는다면 로저가 내 질문에 위의 답변을했다고 생각합니다. 내가 전에 말했듯이, 나는 여전히 정책에 대한 내 머리를 싸려고 노력하고있다 ... – Arthur

1

정책은 일반적으로 클래스 동작에 영향을주는 매개 변수입니다.

클래스에서 정책을 추출하는 것은 사실 상당히 어렵습니다. 다른 정책에 영향을주지 않고 정책을 변경할 수 있도록 정책이 직교 개념을 커버해야하므로 더 어려울 수 있습니다 ... 이것은 상상할 수있는 것처럼 상당히 도전적입니다. .

정책 사용에 대한 좋은 예를 보려면 Loki::Singleton을 찾아보십시오.이 책은이 책에서 모두 설명되어 있습니다.

template 
< 
    typename T, 
    template <class> class CreationPolicy = CreateUsingNew, 
    template <class> class LifetimePolicy = DefaultLifetime, 
    template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL, 
    class MutexPolicy = LOKI_DEFAULT_MUTEX 
> 
class SingletonHolder; 

인상적이지 않습니까?

정책 기반 디자인의 원칙은 클래스의 다양한 동작을 시도하고 분해하여 독자적으로 추론 할 수 있도록하는 것입니다. 함께

자, 이제 내가 템플릿 매개 변수의 세트 번호로 클래스를 필요로하는 아이디어와 아주 편하지 아니라고 인정합니다, 제가 개인적으로 선호 한 무언가 : 마지막으로 정말 도움이 될 수 없습니다

template 
< 
    class T, 
    class CreationPolicy = CreateUsingNew<T>, 
    class LifetimePolicy = DefaultLifeTime<T>, 
    class MutexPolicy = LOKI_DEFAULT_MUTEX, 
    template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL 
> 
class SingletonHolder; 

, 당신은 그것을 SingletonHolder 클래스 자체에 전달해야합니다.

template <class T, size_t Param> MyCreationPolicy; 

그리고 그것은 서명을 일치하도록 PARAM의 주어진 값을 포장 할 필요없이 직접 사용

그러나 내가 여기에 정책을 교환하기 쉽게 찾을, 그것은 나를 같은 정책을 정의 할 수 있습니다.

+0

설명 주셔서 감사합니다! 매우 도움이된다! – Arthur