2009-06-24 3 views
3

Я не знаю, есть ли официальное название для этого, но я играл с тем, что мне нравится называть «самозаготовительным» образцом. В принципе, это когда абстрактный базовый класс действует как фабрика для себя. Позвольте мне объяснить:Шаблон «Self-Factory»

У меня есть объекты Foo и объекты Bar в моей системе, которые используются через интерфейсы FooInterface и BarInterface. Мне нужно дать своим клиентам правильный тип Foo и Bar. Решение о том, какой конкретный объект Foo для создания создается во время компиляции. Например, если вы компилируете на win32, вы хотите создавать только объекты Win32Foo, а при компиляции на OSX вы хотите создавать только объекты OSXFoo и т. Д. Но решение о том, какой конкретный объект Bar создать, производится во время выполнения, на основе ключевой строки.

Теперь, мой вопрос касается наилучшего способа реализации этой схемы. Один из способов я придумываю использует регулярные заводы:

shared_ptr<FooInterface> foo = FooFactory::create(); 
shared_ptr<BarInterface> happyBar = BarFactory::create("Happy"); 
shared_ptr<BarInterface> sadBar = BarFactory::create("Sad"); 

Другой способ заключается в использовании того, что я называю «само-заводы»:

shared_ptr<FooInterface> foo = FooInterface::create(); 
shared_ptr<BarInterface> happyBar = BarInterface::create("Happy"); 
shared_ptr<BarInterface> sadBar = BarInterface::create("Sad"); 

Каковы плюсы и минусы каждого подхода, как из с точки зрения удобства использования и с архитектурной точки зрения?

+0

Я думаю, что то, что вы предлагаете в качестве самозавода, также называется шаблоном прототипа. Вероятно, вы можете просмотреть литературу по этой схеме идей. –

ответ

2

заводы имеют два общих применений:

1) принимает решение динамического полиморфного типа во время выполнения, на основе параметров и/или глобальное состояние (например, конфигурация). Ваш шаблон делает это.

2) Зависимость впрыска: вместо использования статической функции для создания объектов используйте фабрику объект, так что тип возвращаемого объекта может быть сконфигурирован вызывающим абонентом, пройдя на любой завод, который им нужен. Ни один из этих шаблонов не предусматривает этого. Кроме того, ваш второй шаблон даже не позволяет устанавливать статическую зависимость (используя функции шаблона, которые принимают заводский класс в качестве параметра шаблона), поскольку интерфейс и фабрика одинаковы.

Таким образом, один контур вашего шаблона (и ваших обычных фабрик) заключается в том, что инъекция зависимостей не поддерживается. Существует одна и только одна функция вызова для получения объекта, который является FooInterface, и это FooInterface :: create(). Я не буду спорить, почему инъекция зависимости полезна, просто укажите, что если вы построите этот способ, вы не сможете его использовать.

1

Обычно фабрики отвечают за создание объектов целых иерархий классов. Таким образом, в вашем примере у вас будет Win32Factory, OSXFactory и т. Д. Одним из преимуществ этого является то, что вы должны выбрать конкретную реализацию (win32/unix/etc) только один раз - во время создания фабрики, но если вы используете интерфейсы классов, у вас есть постоянно предоставлять информацию о ОС.

Если у вас есть только два класса (Foo и Bar), я не уверен, если это стоит усилий для создания заводов для них, а не просто использовать метод интерфейсов create.

О, и когда интерфейс имеет метод создания объектов своего типа, он называется factory method pattern.

3

Я бы сделать улучшение:

shared_ptr<FooInterface> foo = Factory<FooInterface>::create(); 
shared_ptr<BarInterface> happyBar = Factory<BarInterface>::create("Happy"); 
shared_ptr<BarInterface> sadBar = Factory<BarInterface>::create("Sad"); 

Вы бы объявить:

template <class I> 
struct Factory { }; 

А затем для каждого интерфейса, который нуждается в фабрику, вы могли бы сделать это:

template <> 
struct Factory<FooInterface> 
{ 
    static FooInterface create(); 
}; 

Это позволяет сохранить заводскую реализацию отдельно от декларации интерфейса, но при этом использовать систему типов для bi во время компиляции.

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

  • Нет связанных вопросов^_^