Russian Qt Forum
Ноябрь 24, 2024, 00:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Обсуждение архитектуры приложения. Пример с фабричным методом  (Прочитано 32747 раз)
nata267
Гость
« : Июнь 13, 2012, 11:19 »

Взято из QtDesigner.

В приведенном примере - фабрика оболочек(расширений) объектов системы - ExtensionFactory. Например, список свойств объекта является оболочкой объекта. У одного и того же объекта в системе может быть несколько оболочек(расширений) разного плана. Получить их можно с помощью менеджера расширений.
 
Менеджер регистрируюет каждую конкретную фабрику расширений под определенным id фабрики. По id фабрики менеджер определяет с помощью какой конкретной фабрики создавать конкретную оболочку(расширение) объекта. Например, PropertySheetExtension -  оболочка, хранящая свойства объекта. ContainerExtension - это оболочка-контейнер объекта и.т.д.

В первом прикрепленном файле - собственно фабрика. Чтобы не порождать подклассы фабрик используются шаблонные классы.
Во втором прикрепленном файле - менеджер, используемый для регистрации фабрик.
В третьем прикрепленном файле пример объектов которые порождаются фабриками.

Вот несколько фабрик:

Код:
typedef ExtensionFactory<QDesignerContainerExtension, QStackedWidget, QStackedWidgetContainer>  QDesignerStackedWidgetContainerFactory;
typedef ExtensionFactory<QDesignerContainerExtension, QTabWidget, QTabWidgetContainer> QDesignerTabWidgetContainerFactory;
typedef ExtensionFactory<QDesignerContainerExtension, QToolBox, QToolBoxContainer> QDesignerToolBoxContainerFactory;
typedef ExtensionFactory<QDesignerContainerExtension, QScrollArea, QScrollAreaContainer> QScrollAreaContainerFactory;
typedef ExtensionFactory<QDesignerContainerExtension,  QDockWidget, QDockWidgetContainer> QDockWidgetContainerFactory;

Фабрики  создаются и регистрируются так:

Код:
QExtensionManager *mgr = new QExtensionManager(this);
const QString containerExtensionId = Q_TYPEID(QDesignerContainerExtension);

QDesignerStackedWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
QDesignerTabWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
QDesignerToolBoxContainerFactory::registerExtension(mgr, containerExtensionId);
QDockWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
QScrollAreaContainerFactory::registerExtension(mgr, containerExtensionId);

Пример использования объектов, порожденных фабриками:
Код:
...
if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
        for (int i=0; i<container->count(); ++i) {
            QWidget *page = container->widget(i);
...
}
    }
...
« Последнее редактирование: Июнь 18, 2012, 20:28 от nata267 » Записан
nata267
Гость
« Ответ #1 : Июнь 13, 2012, 11:27 »

Правда синтаксис функции - qt_extension не могу до сих пор понять. но смысл - manager->extension(object, iid)

т.е. вместо

QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)

можно записать так:

QDesignerContainerExtension *container = qobject_cast<QDesignerContainerExtension*>(core()->extensionManager()->extension(widget, Q_TYPEID(QDesignerContainerExtension)));
« Последнее редактирование: Июнь 13, 2012, 14:30 от nata267 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Июнь 14, 2012, 10:43 »

На мой взгляд предложенная схема обсуждения неудачна. Типа "вот тролли применили паттерн, давайте у них учиться". Никто не спорит, изучение исходников Qt дает больше чем просто использование. Но все-таки просматривая исходники мы не проектируем, не принимаем решений и не несем за них никакой ответственности. Др словами делать самому и смотреть/понимать как делают другие - совсем не одно и то же.

Также возникает "эффект уже написанного". Если уже есть мощные, развитые классы, то другие часто создаются в угоду им. Поэтому трудно оценить объективный эффект паттерна - возможно и без него было бы неплохо. Ну и вообще, мужики сюда заходят отдохнуть, языком почесать, блеснуть познаниями - а Вы им по рогам кучей классов дизайнера.. Ну кто ж  будет их учить и Вам отвечать?  Улыбающийся

Возвращаясь к фабрике - это один из немногих паттернов с которым все ясно и который трудно спутать с чем-то другим. Обычно "factory" есть и в имени класса. Предполагает набор (хотя бы 2-3 класса) над которым эта фабрика и создается. Типичный пример - набор загрузчиков файлов или набор плагинов. Честно говоря не вижу что тут обсуждать
Записан
alexis031182
Гость
« Ответ #3 : Июнь 14, 2012, 11:07 »

...
Ну и вообще, мужики сюда заходят отдохнуть, языком почесать, блеснуть познаниями - а Вы им по рогам кучей классов дизайнера.. Ну кто ж  будет их учить и Вам отвечать?  Улыбающийся
...
Смеющийся Смеющийся Смеющийся класс! отличный юмор!
Записан
nata267
Гость
« Ответ #4 : Июнь 14, 2012, 11:52 »

На мой взгляд предложенная схема обсуждения неудачна. Типа "вот тролли применили паттерн, давайте у них учиться". Никто не спорит, изучение исходников Qt дает больше чем просто использование. Но все-таки просматривая исходники мы не проектируем, не принимаем решений и не несем за них никакой ответственности. Др словами делать самому и смотреть/понимать как делают другие - совсем не одно и то же.

Также возникает "эффект уже написанного". Если уже есть мощные, развитые классы, то другие часто создаются в угоду им. Поэтому трудно оценить объективный эффект паттерна - возможно и без него было бы неплохо. Ну и вообще, мужики сюда заходят отдохнуть, языком почесать, блеснуть познаниями - а Вы им по рогам кучей классов дизайнера.. Ну кто ж  будет их учить и Вам отвечать?  Улыбающийся

Возвращаясь к фабрике - это один из немногих паттернов с которым все ясно и который трудно спутать с чем-то другим. Обычно "factory" есть и в имени класса. Предполагает набор (хотя бы 2-3 класса) над которым эта фабрика и создается. Типичный пример - набор загрузчиков файлов или набор плагинов. Честно говоря не вижу что тут обсуждать

Это ж ветка - Кладовая готовых решений. Вот нашла решение и разместила его тут. Обсуждать наверно и правда нечего. Если ктото сочтет это полезным - будет использовать. Единственное что я думаю. Ясность моего изложения наверно оставляет желать лучшего. Может быть чего-то и пропустила. Если что пишите. И пример не очень простой для понимания. Хотя есть и посложнее примерчики. Реализация окошка редактирования свойств чего только стоят. Диаграмма на всю стену в офисе получается))) Хотя организовано классно, ибо добавить новый вид свойств, со специфическим редактором оказалось очень легко. Вот сижу ломаю голову как упростить изложение материала)
Записан
nata267
Гость
« Ответ #5 : Июнь 15, 2012, 11:10 »

Еще один пример. Создание окон разного типа.
Окно создается так: ToolWindow::createStandardToolWindow(ToolWindow::PropertyEditor);
« Последнее редактирование: Июнь 15, 2012, 11:12 от nata267 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июнь 15, 2012, 11:25 »

Еще один пример. Создание окон разного типа.
Окно создается так: ToolWindow::createStandardToolWindow(ToolWindow::PropertyEditor);
Несерьезная у них фабрика. Не должен нигде вылазить switch. А inline(ы) вообще так, затычка
Записан
nata267
Гость
« Ответ #7 : Июнь 15, 2012, 11:40 »

Еще один пример. Создание окон разного типа.
Окно создается так: ToolWindow::createStandardToolWindow(ToolWindow::PropertyEditor);
Несерьезная у них фабрика. Не должен нигде вылазить switch. А inline(ы) вообще так, затычка

почему затычка??
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июнь 15, 2012, 11:52 »

почему затычка??
Потому что не пользуемся ToolWindow::CreateStandardToolWindow, который для этого предназначен, а городим еще inline чтобы это же сделать
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июнь 15, 2012, 12:10 »

Смысл фабрики (как я его понимаю) в спекуляции/обыгрывании зарегистрированной мапы. Примеры

Код
C++ (Qt)
// простой пример
CFactoryObject * CMyFactory::GetByID( int ID )
{
TIterator it = mMap.find(ID);
return (it == mMap.end()) ? 0 : it.second->Create();
}
 

Код
C++ (Qt)
// чуть сложнее
CFactoryObject * CMyFactory::GeLoader( int format )
{
TIterator it;
for (it = mMap.begin(); it != mMap.end(); ++it) {
  CLoader * loader = it.second->Create();
  if (loader->AcceptFormat(format)) return loader;
  delete loader;
}
}
 

В первом случае мы довольно легко можем обойтись switch и (пока) забыть об этом. Однако если возникает второй случай - опять придется городить switch, причем обильный и.т.д
« Последнее редактирование: Июнь 15, 2012, 12:28 от Igors » Записан
Akon
Гость
« Ответ #10 : Июнь 15, 2012, 12:15 »

2nata267:
Просьба, вы когда выкладываете решение, поясняйте, зачем оно нужно и, главное, чем оно лучше известных решений. Например, метаобъектная система Qt позволяет сделать так, а на row C++ вы вынуждены будете делать так и т.п.
Записан
nata267
Гость
« Ответ #11 : Июнь 15, 2012, 12:24 »


Код
C++ (Qt)
// простой пример
CFactoryObject * CMyFactory::GetByID( int ID )
{
TIterator it = mMap.find(ID);
return (it == mMap.end()) ? 0 : it->second.Create();
}
 


А что вообще такое it->second и разве не it.second в вашем примере?
И почему в случае если достигнут конец итератора возвращается 0, а не вставка? а в случае когда НЕ достигнут конец вставка (если я не ошибаюсь) вместо найденного значения??

« Последнее редактирование: Июнь 15, 2012, 12:29 от nata267 » Записан
nata267
Гость
« Ответ #12 : Июнь 15, 2012, 12:26 »

2nata267:
Просьба, вы когда выкладываете решение, поясняйте, зачем оно нужно и, главное, чем оно лучше известных решений. Например, метаобъектная система Qt позволяет сделать так, а на row C++ вы вынуждены будете делать так и т.п.

row C++??? what is it? простите мою безграмотность
Записан
kambala
Джедай : наставник для всех
*******
Online Online

Сообщений: 4747



Просмотр профиля WWW
« Ответ #13 : Июнь 15, 2012, 12:31 »

думаю имелось в виду raw (чистый или «голый»)
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Июнь 15, 2012, 12:32 »

А что вообще такое it->second и разве не it.second в вашем примере?
Просто перепутал точку с ->. Подправил, спасибо

row C++??? what is it? простите мою безграмотность
Наверное имеется ввиду "raw" (сырой). И бог с ней, с грамотностью. Лучше знать меньше но основательнее  
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.141 секунд. Запросов: 23.