2014-09-05 3 views
0

Рассмотрим этот «дизайн» (детали реализации опущены):Как я могу улучшить способ создания этого объекта?

struct service {}; 

struct sub { 
    sub(service&) {} 
    service& s_; 
}; 

struct sub_a: sub { 
    sub_a(service&) {} 
}; 

struct sub_b: sub { 
    sub_b(service&) {} 
}; 

struct top { 
    service svc_; 
    sub_ptr sub_; 
}; 

В принципе, мой top объект содержит sub_ptr, но экземпляр принадлежит этому указателю необходим доступ к svc_ для того, чтобы инстанциируемый, который также находится в top. Однако, я хочу, чтобы пользователь top был в состоянии выбрать тип sub (здесь sub_a или sub_b), не предоставляя по телефону svc_.

Мое решение до сих пор, чтобы мой конструктор top, как это:

template <typename SubType> 
top(std::unique_ptr<SubType>): sub_(new SubType(svc_)) {} 

Вот является использование:

auto t = top(std::unique_ptr<sub_b>()); 

Но я не чувствую, что это решение элегантно. Я мог бы написать функции (например, make_top_sub_b()), чтобы скрыть детали, но мне было интересно, как я мог избежать указания фиктивного указателя на мой конструктор? Создание top шаблоном не является вариантом.

Любая идея, как я мог бы улучшить это? Спасибо,

+1

Насколько я вижу, это выглядит как проблема, решаемая шаблоном Factory. Простая версия шаблона Factory - это делегировать конструкцию вашего типа функции, которую вы предлагаете с помощью 'make_top_sub_b'. Я бы сказал, что вы на верном пути. – YoungJohn

ответ

1

Принцип замены Лискова будет слышать, что пользователей из sub_ptr не нужно было знать, какую реализацию он придерживался.

Как sub_ptr обернут в пределах top, вы можете сказать, что top является пользователем.

Построение sub должно выполняться через заводскую установку, а service - ссылки должны иметь срок службы, превышающий срок службы класса, содержащего ссылку.

В вашем случае срок службы служебного объекта находится в top, что означает, что sub должен иметь более короткий срок службы.

У вас может быть класс sub_factory, который является абстрактным и создает его из службы.

например.

struct sub_factory 
{ 
    virtual sub* create(service_ &) const = 0; 
}; 


struct sub_a_factory : sub_factory 
{ 
     // detail, creates sub_a 
}; 

struct sub_b_factory : sub_factory 
{ 
    // detail, creates sub_b 
}; 

top::top(sub_factory const & fact) : 
     sub_(fact.create(svc_)) 
{ 
} 

sub_factory_a afact; 
sub_Factory_b bfact; 
top ta( afact); 
top tb(bfact); 

Обратите внимание, что вы можете использовать список Инициализатора здесь svc_ появляется над sub_ в классе так получает инициированный первый.

+0

Это не то, о чем LSP. Речь идет о различных подклассах 'sub', которые могут использоваться как' sub'. Пользователь может знать, какой из них он создает. (В том же духе вы хотите утверждать, что ваш заводский дизайн не противоречит той же интерпретации LSP, которую вы использовали? Поскольку пользователь фабрики должен знать, какая фабрика она создает) –

+0

Это хорошее решение для меня, спасибо ! – piwi

+0

Создатель может знать, какой из них создан, пользователю не нужно знать, что используется. Да, должно быть возможно заменить любой из них. – CashCow

Смежные вопросы