2010-10-20 11 views
0

Je souhaite placer une partie de la bibliothèque TinyXML dans certaines classes personnalisées de mon projet car je n'ai besoin que de certaines de ses fonctionnalités et je ne souhaite pas tout exposer.Question sur la conception de l'encapsuleur de classes

J'ai un problème où ma fonction XMLDocument::AddNode(...) fait fondamentalement la même chose que ma classe XMLNode est destinée. Je me demandais si quelqu'un pouvait me donner quelques conseils de conception sur la façon d'emballer la bibliothèque TinyXML afin que je ne casse pas l'encapsulation et que mes classes wrapper n'exposent pas la bibliothèque TinyXML au reste de mon code.

class XMLNode 
    { 
    public: 
     XMLNode::XMLNode(); 
     XMLNode::XMLNode(const std::string& element); // Creates a TiXMLElement object 
     XMLNode::XMLNode(XMLNode& nodycopy); 
     XMLNode::~XMLNode(); 

     XMLNode GetFirstChild(); 
     XMLNode GetNextSibling(); 

     std::string GetNodeValue(); 
     std::string GetNodeName(); 

     void AddNodeText(const std::string& text); 
     void AddNodeAttribute(); 

    private: 
     std::string value; 
     std::string nodename; 

     TiXmlElement* thisnode; 
    }; 

//These functions do the same as my AddNode does from XMLDocument, it seems rather silly... 
    XMLNode::XMLNode(const std::string& str_element) 
{ 
    thisnode = new TiXmlElement(str_element.c_str()); 
    nodename = str_element; 
} 

void XMLNode::AddNodeText(const std::string& nodetext) 
{ 
    TiXmlText* text = new TiXmlText(nodetext.c_str()); 
    thisnode->LinkEndChild(text); 
    value = nodetext; 
} 


class XMLDocument 
    { 
    public: 
     XMLDocument::XMLDocument(const std::string& documentname); 
     XMLDocument::~XMLDocument(); 

     void SaveToFile(std::string filename); 
     std::string basicXML(std::string rootnode); 

     void AddNode(XMLNode& node); 
     XMLNode GetXPathNode(const std::string& node); 
     void AppendCloneNodeAsChild(XMLNode& nodetoappend); 

     void SetRoot(XMLNode& rootnode); 
    private: 
     TiXmlDocument document; 
     TiXmlElement root; 
     TiXmlElement currentelement; 

    }; 

void XMLDocument::AddNode(XMLNode& node) // This function does over what XMLNode class is actually for... I just want to add the node to the XMLDocument 
{ 
    std::string val = node.GetNodeName(); 
    TiXmlElement* el = new TiXmlElement(val.c_str()); 
    TiXmlText * txt = new TiXmlText(node.GetNodeValue().c_str()); 
    el->LinkEndChild(txt); 
    document.LinkEndChild(el); 
} 

Quelqu'un peut-il me donner quelques suggestions sur la façon d'envelopper cette correctement et d'exposer uniquement les fonctionnalités de TinyXML que je veux?

Répondre

1

Vous encapsulez déjà le TinyXml document - maintenant vous avez juste besoin de lui déléguer où vous voulez, pour exposer seulement un sous-ensemble de la fonction qu'il fournit.

Remplacer cette

void XMLDocument::AddNode(XMLNode& node) // This function does over what XMLNode class is actually for... I just want to add the node to the XMLDocument 
{ 
    std::string val = node.GetNodeName(); 
    TiXmlElement* el = new TiXmlElement(val.c_str()); 
    TiXmlText * txt = new TiXmlText(node.GetNodeValue().c_str()); 
    el->LinkEndChild(txt); 
    document.LinkEndChild(el); 
} 

avec ce

void XMLDocument::AddNode(XMLNode& node) 
{ 
    document.AddNode(node); 
} 

Ceci est tout à fait légitime puisque vous ne voulez pas exposer pleinement TiXmlDocument aux clients de votre classe. Pensez à la façon dont std::queue et std::stack agissent comme des adaptateurs sur les conteneurs sous-jacents.

+0

Mais mon XMLNode n'est pas compatible avec le TiXmlElement que document.AddNode utilise ... –

+0

@Tony - Je vois, mais puisque 'XmlNode' encapsule' TiXmlElement', vous ne pouvez pas simplement appeler 'document.AddNode (* node .thisnode); –

+0

Donc, vous exposeriez le TiXmlElement? Je suppose qu'il n'y a pas beaucoup d'options, bien que j'imagine que l'exposer en quelque sorte rompt l'idée d'un wrapper ... –

0

Il y a 2 façons de résoudre ce problème.

  1. Dérivation à partir XMLDocument
  2. ayant un objet de XMLDocument et transférer l'appel à elle.