Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Фабрика классов, C++.NET 
:(
    Опции темы
Vyacheslav
Дата 15.3.2005, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



Если в .NET встроенные средства для реализации паттерна "Фабрика классов"


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Borisff2003
Дата 15.3.2005, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 26.2.2004
Где: г. Уфа

Репутация: нет
Всего: 1



Наскока я знаю, нет.
Посмотри здесь заготовки
http://www.dotsite.spb.ru/solutions/patterns/
--------------------
Лень, двигатель прогресса
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 15.3.2005, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



То что там, пример довольно примитивного варианта фабрики, причем в его стандартном исполнении. А где же использование возможностей Атрибутов и Отражения?


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 15.3.2005, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата(Vyacheslav @ 15.3.2005, 02:39)
То что там, пример довольно примитивного варианта фабрики, причем в его стандартном исполнении. А где же использование возможностей Атрибутов и Отражения?


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


--------------------

PM   Вверх
Vyacheslav
Дата 15.3.2005, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



Ну спасибо за азы. Бестолковые, между прочим. Ну уж никак не думал, что "релизовать паттерн" воспримется как "написать паттерн".
Цитата

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

Это то же кстати одно из определений паттерна






--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
[Last]Wizard
Дата 15.3.2005, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 20.7.2004
Где: Минск, Беларусь

Репутация: 4
Всего: 10



Цитата(Vyacheslav @ 15.3.2005, 11:41)
ничего не избретая заново

Вот именно, ничего не изобретая!

Написать паттерн можно просто механически, зная, как он реализуется, не нужно думать над тем, как спроектировать классы, и пр.
Ведь не зря же эти паттерны называются ПАТТЕРНАМИ ПРОЕКТИРОВАНИЯ, а не ПРОГРАММИРОВАНИЯ!
PM ICQ   Вверх
Vyacheslav
Дата 15.3.2005, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



Цитата(Domestic @ 15.3.2005, 12:10)
И при чем тут аттрибуты и рефлекшн????

Приехали.
Абстрактная Фабрика - паттерн, порождающий объекты
Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфирую их конкретных классов

Абстрактная Фабрика очень часто реализуется с помощью патерна Factory Method или еще его называют Virtual Constuctor
В С++ Virtual Constuctor либо имитируется с помощью switch или if, что довольно примитивно и требует при добавлении нового класса вносить изменение в класс Фабрики, либо с помощью
map-таблицы сожержащий некий ключ(например текстовое имя ) и указатель на функцию, создающую объект класса, соответсвующего ключу.
При этом дополнительно требуется перед использованием фабоики, провести процедуру регистрации класса, но при этом фабрика соверршено становится независима от классов, объекты которых она создает.

В .NET имеется куча мета-информации и вполне врзможно создание класса по параметру
Что первое приходит в голову, так это примерно вот это (на первый взгляд, ибо я только в начале .NET)
Код

public __value enum MyClasses { First, Second, Third };

public __gs class MyClassAttr : public Attribute
{
    MyClasses   m_type;
public:
     MyClassAttr(MyClasses  type ) : m_type(type) {}
};

public __gs __abstract class  MyBaseClass
{
...
};


[ MyClassAttr (MyClasses::First)] 
public __gs __abstract class  MyFirstClass : public MyBaseClass

{
...
};

[ MyClassAttr (MyClasses::Second)] 
public __gs __abstract class  MySecondClass: public MyBaseClass

{
...
};

[ MyClassAttr (MyClasses::Third)] 
public __gs __abstract class  MyThirdClass: public MyBaseClass
{
...
};


public __gs class Fabric 
{
    Assemply* library;
    ....
    bool IsEqualAttr(MyClasses, Type)
 public:
   ....
    MyByClass* CreateMyClass(MyClasses attr);

// использовать это можно примерно вот так

MyBaseClass* Fabric::CreateMyClass(MyClasses attr)
{
      
  Type* types[] = library->GetTypes();
   for (int i = 0; i < types->Count; i++)
   {
           //ищем тип с атрибутом MyClassAttr , равным attr
 
           if (IsEqualAttr(attr,types[i] )           {
                // создаем объект  
                 return __try_cast<MyBaseClass*>(Activator::CreateInstance(types[i]))
           }
               

   }
    return NULL;
}





Добавлено @ 13:31
Цитата
Wizard, 15.3.2005,  12:49]Написать паттерн можно просто механически, зная, как он реализуется, не нужно думать над тем, как спроектировать классы, и пр.
Ведь не зря же эти паттерны называются ПАТТЕРНАМИ ПРОЕКТИРОВАНИЯ, а не ПРОГРАММИРОВАНИЯ!


Согласен, но реализация паттерна(имеется в виду дизайн) на конкретном языке ( и платформе ) может быть различна, не говоря уж о квалификации smile того, кто это проектирует


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 15.3.2005, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



Кстати, если заменим enum на String, а при создании объекта Fabric будем передоватьимя сборки, то получаем фабрику классов, совершеено независимую от классов, которые она будет создавать
Но, естесвенно, это всего лишь первый набросок, поэтому и возник вопрос. Может кто уже давно сделал лучше.


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 15.3.2005, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата
Приехали.
Абстрактная Фабрика - паттерн, порождающий объекты
Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфирую их конкретных классов

Гоф цитировать мне не надо, а лучше взглянуть на класс диаграмму для этого паттерна. И узнать, что все-таки у них каждая конкретная фабрика - сабкласс AbstractFactory знает о тех объектах, которые она должна произвести.
Цитата
●    ConcreteFactory (MotifWidgetFactory, PMWidgetFactory) implements the operations to create concrete product objects.


Цитата
В С++ Virtual Constuctor либо имитируется с помощью switch или if, что довольно примитивно и требует при добавлении нового класса вносить изменение в класс Фабрики, либо с помощью
map-таблицы сожержащий некий ключ(например текстовое имя ) и указатель на функцию, создающую объект класса, соответсвующего ключу.


Интересно, и где это в абстрактной фабрике свичи, ифы или мапы? Хотя бы на пример в Гамме посмотри...

Цитата
Кстати, если заменим enum на String, а при создании объекта Fabric будем передоватьимя сборки, то получаем фабрику классов, совершеено независимую от классов, которые она будет создавать
Но, естесвенно, это всего лишь первый набросок, поэтому и возник вопрос. Может кто уже давно сделал лучше

Ничего особо хорошего в этом методе нет, поскольку рефлекшн - не самый быстрый способ создать класс.
Никто конечно не мешает таким образом реализовать паттерн. Только вот он никоим образом не будет подходить всем и вся. Потому, что основная мотивация абстрактной фабрики (смотреть опять-таки ГоФ)
Цитата
●    a system should be independent of how its products are created, composed, and represented.
●    a system should be configured with one of multiple families of products. 
●    a family of related product objects is designed to be used together, and you need to enforce this  constraint. 
●    you want to provide a class library of products, and you want to reveal just their interfaces, not  their implementations. 

Заметь - нигде не сказано, что фабрика не должна о чем-то знать. СИСТЕМА не должна знать. Главная цель - иметь возможность легко создавать группы взаимозаменяемых объектов, причем с минимальным вмешательством в систему. И способы, описанные в Дизайн Паттернах хороши и тем, что они служат поставленной задаче, и своей простотой.

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

Цитата
Ну спасибо за азы. Бестолковые, между прочим. Ну уж никак не думал, что "релизовать паттерн" воспримется как "написать паттерн".

Если тебя не поняли - это отчасти и твоя вина. В английском техническом языке "to realize" означает "make real or concrete; give reality or substance to; "our ideas must be substantiated into actions"".
Весьма странные слова для модератора.


--------------------

PM   Вверх
[Last]Wizard
Дата 15.3.2005, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 20.7.2004
Где: Минск, Беларусь

Репутация: 4
Всего: 10



Vyacheslav, если тебе нужна фабрика, которая
Цитата(Vyacheslav @ 15.3.2005, 12:27)
соверршено становится независима от классов, объекты которых она создает

то посмотри Activator.CreateInstance().

Хотя до паттерна "Абстрактная фабрика" это не дотягивает.

PM ICQ   Вверх
Vyacheslav
Дата 15.3.2005, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



Цитата(Domestic @ 15.3.2005, 19:22)
Интересно, и где это в абстрактной фабрике свичи, ифы или мапы? Хотя бы на пример в Гамме посмотри...

То что одним из возможных вариантов реализации Абстрактной Фабрики явлется реализация посредством Фабричного Метода - это, надеюсь возражений не вызывает? Если вызывает- отсылаю к Гамму. Смотрим Фабричный метод. Там используется класс Creator, который может содержать параметризованный фабричный метод
Так если Вы заглянете в книжку, то увидидите то, что в реализации для этого метода на С++ используется конструкция if.
Код

Product* Creator::Create(ProductID id)
{
if (id == MINE) return new MyProduct;
if (id == YOURS) return new YourProduct;
// выполнить для всех остальных продуктов ... например еще штук для 20 :) 

return 0;
}

smile Это к вопросу о советах насчет куда глядеть
Это во первых. А во вторых, надо понимать, что там даны всего лишь примеры для иллюстрации того, как реализация паттерна будет выглядеть на конкретном языке и для определенного примера. К тому же качество кода в примерах весьма посредственное, но другого там и не требовалось. Ибо цель примеров - донести идею, а не научить программировать. И естественно для С++ это можно реализовать более удачно например так
Цитата(Domestic @ 15.3.2005, 19:22)
Если тебя не поняли - это отчасти и твоя вина. В английском техническом языке "to realize" означает "make real or concrete; give reality or substance to; "our ideas must be substantiated into actions"".
Весьма странные слова для модератора.


Ок. В таком случае подскажите, как я должен был сформулировать вопрос, что бы Вы не поняли что собирался не описывать паттерн, а используя уже имеющиеся описания, "реализовать"(извините другого слова подобрать не смог) его применительно к решению конкретной задачи и конкретной языковой среды?










--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 15.3.2005, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата
То что одним из возможных вариантов реализации Абстрактной Фабрики явлется реализация посредством Фабричного Метода - это, надеюсь возражений не вызывает? Если вызывает- отсылаю к Гамму. Смотрим Фабричный метод. Там используется класс Creator, который может содержать параметризованный фабричный метод


Вызывает. это другой паттерн, никак не абстрактная фабрика.

Цитата
а используя уже имеющиеся описания, "реализовать"(извините другого слова подобрать не смог) его применительно к решению конкретной задачи и конкретной языковой среды?


это зависит от задачи, а о конкретной задаче пока разговора не было. Если действительнo в runtime неизвестно, объекты каких классов надo создать, тo да, такой вариант имеет место быть. Хотя oбъект можнo создавать не по аттрибуту, а по типу или стринговому названию класса - как подсказал [Last]Wizard.
http://msdn.microsoft.com/library/default....stancetopic.asp
Так прощe.


--------------------

PM   Вверх
Vyacheslav
Дата 15.3.2005, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



Цитата
Vyacheslav, если тебе нужна фабрика, которая
Цитата(Vyacheslav @ 15.3.2005, 12:27)
соверршено становится независима от классов, объекты которых она создает

то посмотри Activator.CreateInstance().

Хотя до паттерна "Абстрактная фабрика" это не дотягивает.

Спасибо. Это как раз первое, за что я зацепился.
Это естественно не фабрика, другое дело - это, по всей видимости, можно эффективно использовать при создании фабрики


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 15.3.2005, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 2
Всего: 59



[/code]
Цитата(Domestic @ 15.3.2005, 20:17)
Хотя oбъект можнo создавать не по аттрибуту, а по типу или стринговому названию класса - как подсказал [Last]Wizard.


Дедо в том, что завязка непосредственно на тип просто перемещает if'ы (или что то вместо них) в другое место. Мне приходит откуда-то некая информация , по которой я должен созлать экземпляр класса. Соответсвенно мне все равно придется где то иметь код, который доджен сопоставить значение этой информации с типом. Естественно хочется, что бы при добавлении нового класса, не требоавалось лезть туда и снова что то добавлять. В идеале , нужно сделать так, что бы вообще не требовалась перекомпиляция основной приложения. Достаточно было бы добавить класса в библиотеку (в дополнительную сборку).
Во всяком случае такой код уже работает
Требуемый экземпляр класса создается на основании значения свойства MsgType класса CMessage
Код


IExecutor* CExecutorHelper::ExecutorCreate(CMessage* Message, CConnection* Connection)
{
    Type* type = FindType(Message);
    Object* params[] = {Message, Connection };
    return __try_cast<IExecutor*>(type?Activator::CreateInstance(type,params ):NULL);
}

System::Type* CExecutorHelper::FindType(CMessage* Message )
{
    Type* types[] = Assembly::GetExecutingAssembly()->GetTypes();
    for(int i = 0; i < types->Count; i++) {
        Type* type = types[i];
        if (!type->IsAbstract && type->IsSubclassOf(__typeof(IExecutor))){
            Object* attribs[] =  type->GetCustomAttributes(__typeof(ExecutorType), false);
            if (attribs->Count && 
                __try_cast<ExecutorType*>(attribs[0])->MsgType == Message->MsgType) {
                    return type;
            }
        }
    }        
    return NULL;
}



При необходимости добавить еще одни класс(CTestExecutor)например достаточно
добавить
Код

[ExecutorType(MessageType::Test)]
__gc class CTestExecutor : public IExecutor
{
public:    
    CTestExecutor(CMessage* Message, CConnection* Connection)
        :IExecutor(Message, Connection) {}
    void Execute(void); 
};



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

void CConnection::AsyncExecutor(Object* State)
{
    Interlocked::Exchange(&m_active,1);
    while(m_active) {
        while (CMessage* Message = PeekIncoming()) {
                                                // для данного сообщения создаем соответствующий executor
            IExecutor* executor = CExecutorHelper::ExecutorCreate(Message, this);
            if (executor) {
                executor->Execute();
            }
        }
        m_threadState->WaitOne();
    }
    




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 15.3.2005, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Ну в такой ситуации - я согласен. Если б сначала написал о задаче, и разговора б не было smile


--------------------

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1374 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.