JsonCpp:高效序列化与反序列化指南
目录
1.Json数据格式
2.JsonCpp介绍
2.1序列化接口
2.2反序列化接口
2.3使用工厂模式的优点
1.Json数据格式
{"姓名" : "xx","年龄" : 18,"成绩" : [88.5, 99, 58]
}
[{"姓名":"⼩明", "年龄":18, "成绩":[23, 65, 78]},{"姓名":"⼩红", "年龄":19, "成绩":[88, 95, 78]}
]
这一行行的叫键值对,左边是键,右边是值,键必须是字符串,可以单独构建数字,不是一定要键值对
class Json::Value{Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取
数据都可以通过Value& operator[](const std::string& key);//简单的⽅式完成 val["name"] =
"xx";Value& operator[](const char* key);Value removeMember(const char* key);//移除元素const Value& operator[](ArrayIndex index) const; //val["score"][0]Value& append(const Value& value);//添加数组元素val["score"].append(88); ArrayIndex size() const;//获取数组元素个数 val["score"].size();bool isNull(); //⽤于判断是否存在某个字段std::string asString() const;//转string string name =
val["name"].asString();const char* asCString() const;//转char* char *name =
val["name"].asCString();Int asInt() const;//转int int age = val["age"].asInt();float asFloat() const;//转float float weight = val["weight"].asFloat();
bool asBool()const;//转bool bool ok=val["ok"].asBool()'
};
也就是你可以通过Json::Value val; //定义一个叫val的对象
然后这个val对象中对于键值对需要这样访问val["键"]
如果是数组,可以val[下标]访问
如果是键-值(值是数组),val["键"][下标]
2.JsonCpp介绍
JsonCpp库主要是用于实现Json格式数据的序列化和反序列化,它实现了将多个数据对象组织成Json格式字符串,以及将Json格式字符串解析得到多个数据对象的功能。
主要借助三个类以及其对应的少量的成员函数完成序列化和反序列
2.1序列化接口
class JSON_API StreamWriter {virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {virtual StreamWriter* newStreamWriter() const;
}
2.2反序列化接口
class JSON_API CharReader {virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {virtual CharReader* newCharReader() const;
}
工厂模式分析:
基类StreamWriter中有一个成员函数write,这个是一个纯虚函数,说明这是一个抽象类,不能被实例化,是用来定义接口的规范的
基类StreamWriter中还有一个嵌套类,也就是这个类里面还有一个类叫Factory类,也叫工厂类
子类StreamWriterBuilder继承工厂类,其他抽象类的别的成员变量和函数不会继承,只会继承工厂类中的,然后重写工厂类中的纯虚函数newStreamWriter,这样就可以实现多态
如何实现多态:
假如你要实现自己的序列化方案,就需要写一个子类1,子类1去继承抽象类StreamWrite
然后重写write函数,这个函数中是你自己的序列化方案
写一个子类2,子类2去继承抽象类中的工厂类,然后子类2重写StreamWriteBuilder函数,
这个函数中new一个子类1,然后返回抽象类的指针就行
多态两个条件:
1.通过基类的指针或引用调用,实际调用函数为实际的调用对象
2.完成虚函数重写
2.3使用工厂模式的优点
为什么使用工厂模式,而不是直接一个基类里面包含所有的序列化方案呢?
1.如果直接在基类中全部实现,会导致代码臃肿、耦合紧密且难以维护,而工厂模式通过 “拆分职责 + 多态扩展” 解决了这些问题,任何一种方案的修改(如调整缩进规则)都可能影响整个类的稳定性,风险高。
2.如果要新增一种方案,就需要新增 if-else 先判断是哪种序列化方案,然后再执行对应的代码,但是这样违反了“对修改关闭” 原则,也就是你新增一种序列化方案会修改到原来的代码
3.工厂模式使用多态实现,如果新增一个序列化方案,只需要自己实现两个子类,一个重写write函数,一个返回基类指针实现多态,调用者只需要使用统一的接口write即可
4.工厂模式能降低耦合度,符合开闭原则
以下是官方序列化配置方案的使用方法,官方的配置方案基本能够满足我们的需求
以下是官方反序列化配置方案的使用方法,官方的配置方案基本能够满足我们的需求