Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дизайн класса http запроса, нужен совет 
:(
    Опции темы
SABROG
  Дата 25.5.2010, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Хочу сделать разную реакцию программы на получение ответа от сервера на разные типы запросов. Очередь запросов представлена подобным образом:

// псевдокод
Код

std::vector<Request> queue;


Код

struct Request
{
    enum Type {HtmlPage, File};
    std::string url;
    IODevice* device;
    Type type;
};


Ответ от сервера приходит в один метод типа:

Код

void MyClass::requestFinished(IODevice* device)
{
    Request request = getRequestByDevice(device); // метод проходит по очереди и выцепляет нужный запрос
    if (request == Request::HtmlPage) {
        doHtmlPage();
    }
    else if (request == Request::File) {
        doFile();
    }
}


Думал сделать както-то так:

Код

class AbstractRequest;

std::vector<AbstractRequest> queue;

class AbstractRequest
{
public:
    virtual void do() = 0;
    std::string url;
    IODevice* device;
};

class RequestHtmlPage : AbstractRequest
{
public:
    void do()
    {
        doHtmlPage();
    }
};

class RequestFile : AbstractRequest
{
public:
    void do()
    {
        doFile();
    }
};

void MyClass::requestFinished(IODevice* device)
{
    AbstractRequest request = getRequestByDevice(device); // метод проходит по очереди и выцепляет нужный запрос
    request.do();
}


Но я бы хотел иметь возможность точно определять какого типа объект класса в рантайме. Как я понимаю это единственный вариант при использовании примера выше без использования RTTI:

Код

    AbstractRequest arequest = getRequestByDevice(device);
    RequestHtmlPage* htmlrequest = dynamic_cast<RequestHtmlPage*>(&arequest);
    RequestFile* filerequest = dynamic_cast<RequestFile*>(&arequest);

    if (htmlrequest)
        doStuffForHtmlPage();
    else if (filerequest) {
        doStuffForFile();
    }


У кого есть мысли как это лучше организовать?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
djamshud
Дата 25.5.2010, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Для dynamic_cast используется RTTI. В вашем случае для doStuff..() он не нужен, проще и правильнее организовать специфичные действия прямо в виртуальном do(). Лично я использую проверку на тип только в таких случаях:

Код
class iface{
 virtual foo(iface*);
};

class bar:public iface{
 foo(iface *obj){
  if(dynamic_cast<bar*>(obj)){
   ...
  }
  ...
 }
};


То есть проверяю принадлежность объекта к текущему наследованному типу.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
jonie
Дата 25.5.2010, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



зачем очередь представлена как вектор?... впрочем, не так и важно.
без RTTI - можно ввести поле enum в AbstractRequest и по нему ориентироваться, т.е. без dynamic_cast<>.
Нечто вроде:
1) класс RequestFile, RequestHtml наследники от AbstractRequest , получают данные в методе do().
2) классы обработчики реквестов, их экземпляры подтягиваются в конце do() (ну или у вас где dinamic_cast) через фабрику.. вот тут можно разрулить - подтягивать ли фабрикой новые экземпляры обработчиков, или выдавать singleton-ы.... Фабрика может судить о том что ей создать исходя из поля в AbstractRequest 

Сумбурно как-то.. но наверно можно развить идею


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SABROG
Дата 25.5.2010, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Вот оно как...

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


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 25.5.2010, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



SABROG, тебе не кажется, что этот вопрос в данном разделе не очень уместен?  smile 
PM   Вверх
mes
Дата 25.5.2010, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



SABROG, имхо разбивать на классы лучше не по запросам, а по обработчикам.. 



--------------------
PM MAIL WWW   Вверх
SABROG
Дата 25.5.2010, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Цитата(bsa @  25.5.2010,  16:11 Найти цитируемый пост)
SABROG, тебе не кажется, что этот вопрос в данном разделе не очень уместен?

Вопрос как бы по дизайну, я не знаю как подобное решают профессиональные программисты.  smile 

Цитата(mes @  25.5.2010,  17:45 Найти цитируемый пост)
SABROG, имхо разбивать на классы лучше не по запросам, а по обработчикам.. 

Я не совсем понял о чем идет речь. Структура остается структурой, но завести 2 класса в которые она будет передаваться и где будет происходить обработка, типа этого?

Код

struct Request
{
    enum Type {HtmlPage, File};
    std::string url;
    IODevice* device;
    Type type;
};

class HtmlHandler {
public:
    explicit HtmlHandler(const Request& request)
    doStuff();
};

class FileHandler {
public:
    explicit FileHandler(const Request& request)
    doStuff();
};

void MyClass::requestFinished(IODevice* device)
{
    Request request = getRequestByDevice(device); // метод проходит по очереди и выцепляет нужный запрос
    if (request == Request::HtmlPage) {
        htmlHandler handler(request);
        handler.doStuff();
    }
    else if (request == Request::File) {
        fileHandler handler(request);
        handler.doStuff();
    }
}


Или ты имеешь ввиду шаблонные классы с типовой специализацией?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
jonie
Дата 25.5.2010, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



вместо 
Цитата

Код

    Request request = getRequestByDevice(device); // метод проходит по очереди и выцепляет нужный запрос
    if (request == Request::HtmlPage) {
        htmlHandler handler(request);
        handler.doStuff();
    }
    else if (request == Request::File) {
        fileHandler handler(request);
        handler.doStuff();
    }

я предлагал делать фабрику, и извлекать экземпляры обработчиков из неё - if-ы уйдут банальнейше...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SABROG
Дата 25.5.2010, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Цитата(jonie @  25.5.2010,  20:02 Найти цитируемый пост)
я предлагал делать фабрику, и извлекать экземпляры обработчиков из неё - if-ы уйдут банальнейше... 

Я понял, но нужно рассмотреть несколько реализаций фабрик, которая мне бы подошла, а то ведь тот же паттерн Factory завязывается на виртуальном наследовании, а у меня тут поле Type. Я где-то видел фабрику, которая генерила объекты по строковому параметру типа f->create("automobile"), вероятно мне придется сделать что-то похожее, но типа такого f->create(Request::HtmlPage), ну и request->doStuff().


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
jonie
Дата 25.5.2010, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата

но типа такого f->create(Request::HtmlPage)
у вас в рексесте есть Type, используйте его...Моё личное мнение - если у вас есть возможность уйти от виртуальности, то уходите -- в дальнейшем упростит отладку и поиск багов
Цитата

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

Это сообщение отредактировал(а) jonie - 25.5.2010, 21:16


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SABROG
Дата 25.5.2010, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Цитата(jonie @  25.5.2010,  21:15 Найти цитируемый пост)
у вас в рексесте есть Type, используйте его

Значит я все-таки не до конца тебя понял. Ты предлагаешь оставить структуру как есть, но добавить класс, который будет "плодить" функторы разных классов в зависимости от Type'a?

Цитата(jonie @  25.5.2010,  21:15 Найти цитируемый пост)
отродясь такого не было вроде бы...

Abstract Factory


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
jonie
Дата 25.5.2010, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



Цитата

Ты предлагаешь оставить структуру как есть, но добавить класс, который будет "плодить" функторы разных классов в зависимости от Type'a?
yes.  собственно фабрику. Пост мой прочти этот [http://forum.vingrad.ru/index.php?showtopic=301427&view=findpost&p=2158864]  - не нужны будут if-ы, в фабрике можно использовать std::map, да и вообще кастомизировать этот твой if по Type-у как угодно сложно\легко (заивист от фантазии).

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

Цитата

Abstract Factory 
замечу что "абстактная фабрика" ничуть не называется "фабрика" 8-)


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SABROG
Дата 26.5.2010, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Почитал документацию к примерам фабрик PapaFactory и дошел до такого текста:

Цитата

Comparing this latest implementation with our original ifthen.cpp implementation,
it is tempting to think that we may have produced an over-engineered and overcomplex
design to our original problem. This is possibly true. If all we wanted
was to have three functions, halve, square and integer and no scope for extra flexibility,
then there is a strong argument that the original design was the best option.


То есть у меня вообще 2 выходит. Как бы там ни было продолжу копать в направлении фабрик для саморазвития и возможности расширения функционала кода в перспективе.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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