多个序列化目标/格式(非版本)的设计方法 作为成员,无论是静态的、单独的命名空间、通过FRORES-S、甚至通过重载,还是任何其他C++语言特征……/P>
当面临支持多种/不同格式、协议或任何其他类型的类型目标的问题时,最灵活和可维护的方法是什么 是否有任何大会或明确的获奖者 一个简短的说明为什么一个特定的方法有帮助将是伟大的 谢谢多个序列化目标/格式(非版本)的设计方法 作为成员,无论是静态的、单独的命名空间、通过FRORES-S、甚至通过重载,还是任何其他C++语言特征……/P>,c++,C++,当面临支持多种/不同格式、协议或任何其他类型的类型目标的问题时,最灵活和可维护的方法是什么 是否有任何大会或明确的获奖者 一个简短的说明为什么一个特定的方法有帮助将是伟大的 谢谢 [类似于ProtoBufs的建议不应该为了升级而削减它,不管这个特定的impl可能有多灵活:)如果您需要为许多类提供多种输出格式,我会尝试将它变成一个n+m问题,而不是一个n*m问题。我想到的第一种方法是将类简化为某种字典,然后有一种方法将这些字典序列化为每种输出格式。我使用了OpenH323(对VoIP开发人员来说非
[类似于ProtoBufs的建议不应该为了升级而削减它,不管这个特定的impl可能有多灵活:)如果您需要为许多类提供多种输出格式,我会尝试将它变成一个n+m问题,而不是一个n*m问题。我想到的第一种方法是将类简化为某种字典,然后有一种方法将这些字典序列化为每种输出格式。我使用了OpenH323(对VoIP开发人员来说非常有名)从低密度应答机到32xE1边界控制器,可以长期构建大量与VoIP相关的应用程序。当然,它有重大的返工,所以我知道几乎所有关于这个图书馆的日子 在这个库中有一个工具(ASNparser),它将ASN.1定义转换成容器类。还有一个框架允许使用更高层抽象对这些容器进行序列化/反序列化。注意它们是自动生成的。他们支持ASN.1的几种编码协议(BER、PER、XER),具有非常复杂的ASN sntax和足够好的性能 什么好
- 自动生成的容器类足够适合清晰的逻辑实现
- 我设法在ASN对象层次结构下返工了整个容器层,几乎没有对上层进行任何修改
- 对ASN类的调试功能进行重构(性能)相对容易(我知道,作者并不希望20xE1调用信号被记录在网上)
- 非STL库,此库下有惰性副本。重构的速度,但我希望有STL的兼容性(至少当时)
如果您认为某些问题很奇怪/不够/不是您要求的实际问题,请随意评论。假设您拥有对必须序列化的类的完全访问权限。您需要向类添加某种形式的反射(可能包括抽象工厂)。有两种方法可以做到这一点:1)一个公共基类或2)一个“traits”结构。然后可以编写与基类/特征结构相关的编码器/解码器 或者,您可以要求该类提供一个将自身导出到boost::any容器的函数,并提供一个将boost::any容器作为其唯一参数的构造函数。如果源数据存储在boost::any对象的映射中,那么将序列化函数编写为多种不同的格式应该很简单
这是我处理这个问题的两种方法。这在很大程度上取决于要序列化的类的相似性以及目标格式的多样性,我会选择上述哪种方法。阅读已经发布的回复,我只能同意中间层方法 基本上,在原始问题中,您有两个不同的层次结构:
- n类
- m协议
Visitor
模式(尽管我很喜欢)只会导致n*m
方法。。。这真的很恶心,是维护噩梦的一个入口。我想你已经注意到了,否则你就不会问了
“明显”的目标方法是采用n+m
解决方案,其中两个层次结构明显分开。这当然引入了中间层
这样的想法就是ObjectA->MiddleTier->Protocol1
基本上,协议缓冲区就是这样做的,尽管它们的问题是不同的(通过协议从一种语言到另一种语言)
可能很难确定中间层:
- 性能问题:“翻译”阶段会增加一些开销,现在从1增加到2,虽然这可以减轻,但您必须继续努力
- 兼容性问题:例如,某些协议不支持递归(xml或json不支持递归,edifact不支持递归),因此您可能必须采用最不常见的方法,或者找到模拟此类行为的方法
- int
- 弦
- 列表
- 字典
组合模式来组合它们
当然,这只是第一步。现在您有了一个框架,但没有消息
您应该能够以原语的形式指定消息(并且现在真正考虑版本化,一旦需要另一个版本就太晚了)。请注意,这两种方法是有效的:
- 在代码规范中:您的消息由原语/其他消息组成
- 使用代码生成脚本:这似乎有些过分,但是。。。为了完整起见,我想我会提到它,因为我不知道你真正需要多少信息:)
关于执行问题:
Herb Sutter和Andrei Alexandrescu在他们的C++编码标准中说
首选非成员非好友方法
这非常适用于MiddleTier->Protocol
step>创建Protocol1Protocol1 myProtocol;
myProtocol << myMiddleTierMessage;
// 1 - Your BOM
class Foo {};
class Bar {};
// 2 - Message class: GetUp
class GetUp
{
typedef enum {} State;
State m_state;
};
// 3 - Protocl class: SuperProt
class SuperProt: public Protocol
{
};
// 4 - GetUp to SuperProt serializer
class GetUp2SuperProt: public Serializer
{
};
// 5 - Let's use it
Foo foo;
Bar bar;
SuperProt sp;
GetUp getUp = GetUp(foo,bar);
MyMessage2ProtBase.serialize(sp, getUp); // use GetUp2SuperProt inside