QHash функциональных указателей для установки переменных после разбора XML: insane? - PullRequest
1 голос
/ 13 апреля 2011

Я анализирую и храню данные, полученные с сервера, в формате XML.Приложение представляет собой тонкий клиент, который очень часто запрашивает данные на стороне сервера.Некоторые из переменных будут Uris, которые вызывают больше сетевых вызовов.Данные имеют вид:

<object>
    <var1>value</var1>
    ...
    <varN>value</varN>
</object>

В объекте ~ 50 переменных.Объект зеркалируется классом MyObject, который имеет методы получения и установки для всех переменных (которые имеют разные типы и будут доступны для различных других классов).

Я использовал QXmlStreamReader, что хорошо,но в итоге у меня много

if (reader.name() == "var1")
{
    ...
}

записей, и я думаю, что должен быть лучший способ?

Я написал несколько быстрых прототипов кода, в которых MyObject имеет функцию, которая принимает (name, entry) и индексирует name в QHash указателей на функции, который возвращает установщик на вход, который он вызывает, передавая entry,Это похоже на un-Qt-ish, и похоже на то, что запутает возможного будущего сопровождающего:

В заголовке:

typedef void (Foo::*setValue)(QString& value);
QHash<QString, Foo::setValue> m_settersMap;

.cpp:

MyObject::MyObject(QObject *parent) :
    QObject(parent)
{
    m_settersMap["var1"] = &MyObject::setVar1;
    m_settersMap["var2"] = &MyObject::setVar2;
    ...
    m_settersMap["varN"] = &MyObject::setVarN;
}

void MyObject::set(QString &name, QString &entry)
{
    MyObject *foo = this;
    MyObject::setValue setter;
    setter = m_settersMap.value(key);
    (*foo.*setter)(value);
}

void MyObject::setVar1(QString &entry)
{
    m_foo1 = entry;
}

...

и из обработчика XML:

MyObject foo;

...

if(reader.isStartElement())
{
    foo.set(reader.name(), reader.readEntryText());
}

Таким образом, в обработчике XML гораздо меньше копий-пасты, но есть дополнительные накладные расходы на QHash и возможную путаницу с не простой реализацией (и мое надоедливое подозрениеэто не способ сделать это).

Так это законно или безумно, и я что-то упустил ослепительно очевидное?

1 Ответ

1 голос
/ 13 апреля 2011

Я бы порекомендовал вам другое, более «простое» решение, которое поможет вам:

1) Имейте намного меньше кода и сделайте ваш код читабельным 2) Не перегружайте другие объекты вызовами функций

Таким образом, вы можете использовать QObject properties , чтобы сделать это. И ваш код будет выглядеть так просто:

// parsing the XML here via QXmlStreamReader
...
QObject *object = new QObject;
...
object->setProperty(reader.name(), reader.value());

И тогда вы можете ссылаться на переменную вашего объекта в коде следующим образом:

QString name = object->property("var1").toString();

Вы можете захотеть расширить QObject, чтобы избавиться от необходимости постоянно вызывать .toString () или что-то в этом роде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...