Russian Qt Forum

Qt => Работа с сетью => Тема начата: boobsik от Август 19, 2009, 02:17



Название: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: boobsik от Август 19, 2009, 02:17
пример, на сокет приходит массив данных "create ellipse..." или "create square...", есть абстрактный класс QFigure и 2 его наследника QEllipse и QSquare, задача создать обьект и вернуть указатель на интерфейс.. Проблема: не существет единого формата сообщения, каждая фигура использует свой протокол инициализации своих параметров, фигур дофига..
помогите прийти к элегантному решению:

Код
C++ (Qt)
class QFigure{
   ...
   static QFigure* create(QByteArray *data){
       ????????????????????????????????????        
   }
   virtual draw() = 0;
};
 
class QEllipse : public QFigure{
...
};
 
class QSquare : public QFigure{
...
};
Код
C++ (Qt)
class QNetShapeCreator : QTcpSocket{
public:
   QNetShapeCreator(){
       connect(this, SIGNAL(readyRead()), this, SLOT(readyReadData()));        
   }
   QDataArray *data;
   QList<QFigure*> figures;
   readyReadData(){
       *data = readAll();
       figures.append(QFigure::create(data));
   }
};
необходимо избежать необходимости редактирования статического методе create(QByteArray *data) абстрактного класса QFigure при добавлении новых фигур


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: Rcus от Август 19, 2009, 03:48
Другому я бы посоветовал прочитать GoF и может быть Александреску, но вам же внешние источники не нужны.

Вам нужно множество фабрик и метод идентификации нужной. Можно применять последовательную нумерацию типов или guid. Фабрики объединяются в ассоциативный контейнер, а дальше все элементарно (Впрочем, описанный способ не единственный верный)


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: ритт от Август 19, 2009, 06:20
boobsik, а как датастрим определяет сколько ему нужно считать байт и как их скомпоновать, чтобы получилась строка или рект, или лист?


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: BlackTass от Август 19, 2009, 08:17
сейчас как раз работаю над приложением с похожим протоколом, но у меня известно что команды небольших размеров (не более 4кб) и после отсылки одного запроса клиент будет ждать и ничего больше не слать, а если что-то пошлет то сам дурак, следовательно у меня нет маркеров окончания пакета. При возможности длинных сообщений или последовательных сообщений стоит задуматься о маркировании конца пакета (только не забудьте про байтстаффинг).
Возвращаясь к описанной проблеме. Опять же на моем примере. Есть базовый класс BaseAcceptor, у которого куча наследников (обработчиков соответствующих типов сообщений) и класс BaseProxyAcceptor, который имеет всего два пьюр метода createAcceptor и getAcceptorType. Первый сооттветственно создает новый инстанс некоего аксептора, а второй возвращает идентификатор этого типа аксептора. Есть ассоциативный массив в котором хранятся инстансы прокси-классов с идентификаторами в качестве ключей. И есть некий метод некого класса, который занимается раздачей сестрам по серьгам. Он читает пришедшие данные, смотрит тип сообщения (в вашем случае это комбинация первых двух слов) и создает аксептор через соответствующий прокси.
При желании можно не городить отдельные прокси-классы и перенести их методы в сам аксептор, но это уже как кому больше нравится.


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: ритт от Август 19, 2009, 08:39
как всё сложно :)
а я приверженец CreatorBase'ов...:P


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: whirlwind от Август 19, 2009, 09:29
возможно,  QEllipse, QSquare и прочие оформить как плагины, по сети передавать названия файлов, через QPluginLoader загружать


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: BRE от Август 19, 2009, 09:51
Делаем фабрику, которая может создавать объекты по имени.
Парсим входящую команду на предмет какая фигура создается (берем тип фигуры идущей после create), с помощью фабрики создаем объект. В параметрах передаем оставшуюся часть команды, эта строка передается в конструктор конкретной фигуры, в котором парсится для определения параметров.


Название: Re: Создание обьекта в зависимости от пришедших на сокет данных
Отправлено: boobsik от Август 19, 2009, 13:07
boobsik, а как датастрим определяет сколько ему нужно считать байт и как их скомпоновать, чтобы получилась строка или рект, или лист?
обьекты сами себя инициализировать будут, они принимают массив данных в качестве параметра, а потом просто удалят те данные, которые относятся непосредственно к ним и вернут управление ObjectCreator'у