Russian Qt Forum

Программирование => С/C++ => Тема начата: FakeMoNEy от Июль 03, 2013, 22:38



Название: Объясните пожалуйста паттерн фабрика
Отправлено: FakeMoNEy от Июль 03, 2013, 22:38
Читаю С. Дьюхерста С++ Священные знания.
Там объясняется фабричный метод.
Вроде понятно обьект генерирует информацию о себе при этом мы не заботимся о том кто он конкретно.
Там приведен пример
Код:
class Temp : public Employee {
   public:
      //...
      TempInfo *genInfo() const
         { return new TempInfo( *this ); }
      //...
};
Temp это служащий наследуемый от Employee при этом он может генерировать информацию о себе.
Код:
class Employee {
   public:
      //...
      virtual HRInfo *genInfo() const = 0; // Фабричный метод
      //...
};
Код:
Employee *e = getAnEmployee();
//...
HRInfo *info = e>genInfo();         // используется Фабричный метод
1)TempInfo должен быть наследником HRInfo?
2)Разве все равно не придется спросить тип служащего по какой-то внутренней информации, я имею ввиду не проще было бы ввести идентификатор(номер для типа служащего) чтобы просто определять кто он(рабочий, секретарь, водитель), хотя у разных рабочих разные поля, но тогда придется спросить о его типе как использовать объект о котором мало знаешь, чем это удобно?
3)Приведите пожалуйста пример фабрики другого плана может более наглядного, читаю теорию опыта пока мало но бездумно использовать патерны не хочу, объясните суть пожалуйста.


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Old от Июль 03, 2013, 22:45
Там приведен пример
Там ошибка в примере. Вы правильно его поняли/процитировали?

Фабрика это функция/метод, который может порождать другие объекты.
Простой пример, нужно генерировать разные объекты в зависимости от ключа (не буду мудрить, пусть будет switch):
Код
C++ (Qt)
class Base;
class Obj1 : public Base {};
class Obj2 : public Base {};
class Obj3 : public Base {};
 
class Factory
{
public:
   Base *build( int id ) const
   {
       switch( id )
       {
       case 1:    return new Obj1();
       case 2:    return new Obj2();
       case 3:    return new Obj3();
       }
       return nullptr;
   }
};
 


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Igors от Июль 04, 2013, 16:17
Напр есть 3 загрузчика имеджей
Код
C++ (Qt)
class CLoaderPNG;
class CLoaderJPG;
class CLoaderBMP;
 
И дан файл (полное имя) fileName. При этом однако расширения в имени может и не быть, а на nix системах тип файла должен использоваться вперед расширения. Попробуйте загрузить файл прямолинейно, "без всяких фабрик" просто перебирая загрузчики - их ведь всего 3. Возмжно начав набрасывать схему/псевдокод Вы обнаружите что почему-то получается ужасно коряво  :)


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Bepec от Июль 04, 2013, 21:43
Я п по сигнатурам определял :D


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Igors от Июль 05, 2013, 13:26
Я п по сигнатурам определял :D
Да, это кажется "совсем просто", но начните писать - и попрет из всех щелей  :)


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Bepec от Июль 05, 2013, 14:40
У меня до сих пор работает разборщик файлов по сигнатурам :) Там всё просто, стандарты файлов все описаны.


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Igors от Июль 05, 2013, 15:22
У меня до сих пор работает разборщик файлов по сигнатурам :) Там всё просто, стандарты файлов все описаны.
Без кода (пусть псевдо) мы просто засоряем эфир


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Bepec от Июль 05, 2013, 15:38
Igors вы в курсе сигнатур файлов?
"GIF89" "PNG" "MZђ". Необходимо только прочитать спецификацию файла.

Псевдокод поиска в файле в определённом месте строки? неужели indefOf нуждается в псевдокоде :) Нет ничего сложного. Правда для нескольких десятков специфичных форматов нужен анализ. Но сигнатуры обычно или в начале, или в первой сотне символов.



Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: Авварон от Июль 05, 2013, 19:11
Без кода (пусть псевдо) мы просто засоряем эфир

https://qt.gitorious.org/qt/qtbase/blobs/stable/src/corelib/mimetypes/mime/packages/freedesktop.org.xml


Название: Re: Объясните пожалуйста паттерн фабрика
Отправлено: _Bers от Июль 05, 2013, 19:56
3)Приведите пожалуйста пример фабрики другого плана может более наглядного, читаю теорию опыта пока мало но бездумно использовать патерны не хочу, объясните суть пожалуйста.

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


Задача Фабрики - создание объекта таким образом, что бы скрыть от пользователя правила, по которым создаются объекты.


Вот например: есть задача: нужно создать объект, указав символьное имя его класса.
Как это сделать? А хочется достаточно гибкую и расширяемый механизм. Что бы не городить многочисленные свитчи.

Вот здесь и приходит на помощь фабрика, в которую можно заложить достаточно замысловатые правила, по которым создаются объекты:

Код:
#include <iostream>
#include <string>
#include <map>
using namespace std;

struct Foo{ virtual ~Foo(){}; };
struct Bar0 : Foo {};
struct Bar1 : Foo {};

class Factory
{
  struct Base{ virtual Foo * build()const=0; };

  template<class T> struct Builder : Base{ Foo * build()const { return new T; }; };

   static std::map<std::string, Base*>& GetMap()
   {
      static std::map<std::string, Base*>keys;
      return keys;
   }
public:

  template <class T>  static void reg(const std::string& key)
  {
    cout<< "register: "<<key<<endl;
    GetMap()[key]= new Builder<T>();
  }

  static Foo* build(const std::string& key)  {    return GetMap()[key]->build();  }
};

#define REGISER(class_name) Factory::reg<class_name>(#class_name);

int main()
{
   REGISER(Bar0);
   REGISER(Bar1);

   cout << typeid( *Factory::build("Bar0")).name()<<endl;
   cout << typeid( *Factory::build("Bar1")).name()<<endl;
  
  
}