我可以想到一種方法,基於工廠提供基於標籤的對象。
這裏的困難並不是真的如何去耦每個對象內容的反序列化,而是去耦合一個標籤和一個對象的關聯。
例如,假設您有以下XML
<my_xml>
<bird> ... </bird>
</my_xml>
你怎麼知道你應該建立一個Bird
對象與<bird>
標籤的內容?
有2點的方法有:
- 1對1映射,IG:
<my_xml>
表示單個對象,並且因此知道如何反序列本身。
- 收藏:
<my_xml>
無非對象
首先是相當明顯的,你知道什麼期望,並且可以使用常規的構造的鬆散集合。
C++中的問題是你有靜態類型,這使得第二種情況更加困難,因爲你需要虛擬構造。
虛擬建築雖然可以使用原型來實現。
// Base class
class Serializable:
{
public:
virtual std::auto_ptr<XmlNode*> serialize() const = 0;
virtual std::auto_ptr<Serializable> deserialize(const XmlNode&) const = 0;
};
// Collection of prototypes
class Deserializer:
{
public:
static void Register(Tag tag, const Serializable* item)
{
GetMap()[tag] = item;
}
std::auto_ptr<Serializable> Create(const XmlNode& node)
{
return GetConstMap()[node.tag()]->deserialize(node);
// I wish I could write that ;)
}
private:
typedef std::map<Tag, const Serializable*> prototypes_t;
prototypes_t& GetMap()
{
static prototypes_t _Map;
return _Map;
}
prototypes_t const& GetConstMap() { return GetMap(); }
};
// Example
class Bird: public Serializable
{
virtual std::auto_ptr<Bird> deserialize(const XmlNode& node);
};
// In some cpp (bird.cpp is indicated)
const Bird myBirdPrototype;
Deserializer::Register('bird', myBirdPrototype);
反序列化總是有點在C++中凌亂,動態類型確實有幫助那裏:)
注意:它也可以與流媒體,但更復雜一些到位安全。流式傳輸的問題在於,您應該確保不讀取您的數據並讀取所有數據,以便該數據流處於下一個對象的「良好」狀態:)