С++ «класс-оболочка» для библиотеки XML

Итак, я пытался создать несколько классов вокруг XML-библиотеки xerces, чтобы я мог «скрыть» ее от остальной части моего проекта, базовая библиотека xml остается независимой от остальной части моего проекта.

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

У меня неправильный подход или моя идея «обертки» совершенно глупа?

Я получаю что-то вроде этого:

DOMElement* root();  //in my 'wrapper' class, however this DOMElement is part of the xerces library, at this point my 'wrapper' is broken.  Now I have to use the xerces library everywhere I want to use this function.

Где мое мышление пошло не так?


person Tony The Lion    schedule 14.12.2010    source источник
comment
Что вы делаете с XML? Причина, по которой я спрашиваю, заключается в следующем: вместо того, чтобы обертывать библиотеку XML и выставлять классы-оболочки для вашего кода, почему бы вам не реализовать более простую объектную модель для того, что вы храните в XML, и не выставить это, а затем иметь чистый интерфейс, который может сохраняться /извлечь эту объектную модель из XML?   -  person Nim    schedule 14.12.2010
comment
@Nim, XML используется для связи с клиентом по сетевому соединению. Он сохраняет строку XML в определенном «формате» xml, и мне просто нужно разобрать ее при получении запроса и собрать ее вместе с ответами.   -  person Tony The Lion    schedule 14.12.2010
comment
поэтому я бы сказал, что его роль во всем проекте не очень велика, однако она все же должна быть, так как я не могу изменить клиентскую сторону вещей.   -  person Tony The Lion    schedule 14.12.2010
comment
Итак, в основном он используется для обмена сообщениями, хорошо ли структурирован формат с четко определенным XSD?   -  person Nim    schedule 14.12.2010
comment
@Nim, нет, мне нужно получить формат из существующей программы, которая отправляет запросы и ответы, и основываться на ее содержимом.   -  person Tony The Lion    schedule 14.12.2010
comment
Но это ограниченный формат с хорошо известной структурой? Это нужно делать, чтобы общаться с клиентом, которого вы не контролируете, верно? Тем не менее, принимая во внимание подход разделения, ваша программа всегда имеет дело только с вашим собственным внутренним представлением запроса/ответа, а кодировщик/декодер обрабатывает преобразование в/из проводного формата.   -  person Nim    schedule 14.12.2010


Ответы (3)


Я бы рекомендовал избегать обертки на первом этапе. Просто убедитесь, что уровни и их границы четкие, то есть сетевой уровень заботится о сериализации/десериализации XML, и оттуда вы используете только свои внутренние типы. Если вы сделаете это, а на более позднем этапе вам понадобится заменить xerces на любую другую библиотеку, просто замените уровень сериализации. То есть вместо того, чтобы оборачивать каждый объект XML, просто оберните всю операцию: serialize/deserialize.

person David Rodríguez - dribeas    schedule 14.12.2010

Написание собственного абстрактного интерфейса для библиотеки не является глупой идеей, ЕСЛИ вы планируете изменить или имеете возможность изменить используемую вами библиотеку.

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

Один из примеров реализации:

class XmlElement
{
    private:
    DOMElement element; // point to the element of your library

    public:
    // Here you define how its public interface.
    // There should be enough method/parameter to interact
    // with any xml interface you will use in the future
    XmlElement getSubElement(param)
    {
        // Create the Xmlelement
        // Set the DOMElement wanted
        // return it
    }
}

В вашей программе вы увидите:

void function()
{
    XmlElement root();
    root.getSubElement("value"); // for example
}

Таким образом, в проекте не появляются элементы DOMElement или их функции.

person Phong    schedule 14.12.2010
comment
Недостатком этого подхода является то, что вы потенциально в конечном итоге обертываете множество классов и повторно реализуете множество методов, которые просто делегируют то, что вы храните, - поэтому с вашим XmlElement теперь вам нужно повторно реализовать методы доступа DOMElement - кажется пустой тратой времени времени мне.. Esp. если в конечном итоге формат проводов xml будет выброшен, и вы будете использовать другой формат обмена сообщениями! - person Nim; 14.12.2010
comment
Я с тобой согласен. НО, повторная реализация метода доступа DOMElement - это то, что должна делать оболочка, чтобы скрыть свою реализацию. Именно поэтому я указал в начале темы, что его следует использовать, ТОЛЬКО ЕСЛИ он планирует изменить стоящую за ним библиотеку. Как вы это реализуете внутри, зависит от вас (мой пример может быть не самым лучшим, он может использовать описанную вами систему...). Но интерфейс оболочки должен быть четко определен. - person Phong; 14.12.2010

Как я уже упоминал в своих комментариях, я бы выбрал немного другой подход. Я бы не хотел, чтобы моя кодовая база зависела от конкретного формата обмена сообщениями (xml), который я использую (что, если, например, вы решите изменить xml на что-то другое позже?). Вместо этого я буду работать с четко определенной объектной моделью и иметь простой кодировщик/декодер для обработки преобразования в строку XML и наоборот. Этот кодировщик/декодер будет битом, который я заменю, если основной формат провода изменится.

Декодер будет принимать данные, считанные из сокета, и создавать подходящий объект (с вложенными объектами для представления запроса), а декодер будет принимать аналогичный объект и генерировать из него XML. Если производительность не является первостепенной задачей, я бы использовал библиотеку, такую ​​​​как TinyXML, которая довольно легковесна - черт возьми, вы можете еще больше упростить ее и сделать ее более легкой...

person Nim    schedule 14.12.2010
comment
+1: там, где я работаю, мы называем кодировщики и декодеры адаптерами, роль декодера состоит в том, чтобы принимать некоторые данные на вход и создавать спецификацию, и, если она хорошо написана, она полностью изолирует остальную часть кода (обычно у нас есть декодер интерфейс). Что касается TinyXML: существует TiCpp, который является оболочкой C++ над TinyXML и предлагает приятный интерфейс C++: ticpp.googlecode.com/svn/docs/ticpp.html - person Matthieu M.; 14.12.2010