Брутально и бессердечно о программировании и проектировании
ГлавнаяФорумАртАнтипаттерныТест-драйвЗаметкиВопрос-ответКнигорецензииСправочная

Factory, она же — фабрика

Фабрика, по сути, это виртуальный конструктор. Предположим, у нас есть базовый класс и несколько его наследников. Мы хотим создавать объекты наследников, скрывая их за указателем на базовый класс. Кроме того, мы хотим, чтобы тип наследника определялся в динамике через какой-то параметр. Например, через строковое имя класса, как это сделано в моем примере.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <string>
#include <map>
#include <boost/shared_ptr.hpp>

template <class base>
class factory
{
public:

    typedef boost::shared_ptr<base> base_ptr;

    template <class derived>
    void reg(std::string const& name)
    {
        factories[name] = base_type_ptr(new derived_type<derived>);
    }

    base_ptr create(std::string const& name)
    {
        return factories[name]->create();
    }

private:

    class base_type
    {
    public:

        virtual ~base_type() {}

        virtual base_ptr create() const = 0;
    };

    typedef boost::shared_ptr<base_type> base_type_ptr;

    template <class T>
    class derived_type : public base_type
    {
    public:

        virtual base_ptr create() const
        {
            return new T;
        }
    };

    typedef std::map<std::string, base_type_ptr> factory_container;

    factory_container factories;
};

class furniture
{
public:

    virtual ~furniture() {}

    virtual void show() = 0;
};

class table : public furniture
{
public:

    virtual void show()
    {
        std::cout << "The big black wooden table" << std::endl;
    }
};

class chair : public furniture
{
public:

    virtual void show()
    {
        std::cout << "The old rocking chair" << std::endl;
    }
};

int main()
{
    typedef factory<furniture> furniture_factory;
    typedef furniture_factory::base_ptr furniture_ptr;

    furniture_factory fct;

    fct.reg<table>("Table");
    fct.reg<chair>("Chair");

    furniture_ptr f1 = fct.create("Table");
    furniture_ptr f2 = fct.create("Chair");

    f1->show();
    f2->show();

    return 0;
}
Каждый наследник должен зарегистрироваться в фабрике и передать ей свой идентификатор. После этого фабрика может создавать объекты данного типа.
В большинстве случаев программисты используют фабрики там, где они на самом деле не нужны. Зачастую использование фабрик говорит о переусложненной типизации системы.
Желание воспользоваться фабрикой возникает сразу же после того, как возникает желание отображать языковые функциональные типы в какие-то внешние системы. Например, сохранение на диск или передача по сети. Следует стремиться к таким интерфейсам взаимодействия, для которых достаточным является обмен простыми структурированными данными, а не языковыми функциональными объектами.

Оглавление
Статистика
© 2007—2009 Inside C++ Коммерческие услугиКонтактная информация

. Инверторные сплит системы. монтаж кондиционера! установка кондиционера.. philips 47pfl7603d/10. Порно ролики, секс, эротика - все взаимосвязано и их размещение здесь - то, что вам нужно!. машинки janome Janome 23u excel 23 jem gold 415 521 mini 743 419 419s 204d. аренда склада петербург, аренда склада. light-alloy. Нам! Хорошая уборка помещений. Акция!. канальные кондиционеры lg