委托给子组件的模式
在我正在工作的产品中,非常基本的场景之一是类的序列化。通常,要序列化的类会在其子组件上调用序列化
例如,如果有一个类 st class A{B;C;D;} 那么A.Pack就会调用pack B、C、D 上的函数。
由于有很多这样的类,因此必须一遍又一遍地重复相同的代码模式。 是否可以将此行为封装在模式中(可能使用模板和继承)
In the product I am working, one of very basic scenario is serialization of classes. Typically a class to be serialized calls serialization on its sub-component
e.g. if there is a class s.t. class
A{B;C;D;} then A.Pack will call pack
function on B,C,D.
Since there are many such classes, same pattern of code has to be duplicated over and over again.
Is it possible to encapsulate this behavior in a pattern (possibly using templates and inheritance)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一位评论者写道:
我的(有点邪恶)反驳是是的,如果该方法是析构函数...
输出是相反的顺序,因此要重建对象,您必须解析序列化数据并将每个完成的对象推送到堆栈上。然后,复合对象就会知道要从堆栈中弹出多少个子对象。或者,当然,序列化可以进入中间结构。
另一个有趣的想法是在启动时使用此黑客一次(仅创建和销毁一个特殊对象),其中来自析构函数的回调将创建一个描述原始对象的数据结构。
我还注意到隐式复制构造函数有可能出现类似的滥用,并且可能按正向顺序......
One commenter wrote:
My (slightly evil) counter to that is yes, if the method is the destructor...
The output is in reverse order, so to reconstruct objects you'd have to parse the serialized data and push each completed object on a stack. Composite objects would then know how many children to pop off of the stack. Or, of course, the serialization could go to an intermediate structure.
Another intriguing idea would be to use this hack once at startup (create and destroy only one special object) where the callbacks from the destructors would create a data structure that described the original object.
I also note that implicit copy constructors have potential for similar abuse, and possible in forward order...
使模板执行此操作的常用方法是使用类型列表:
从类型列表创建的组合的正确实现为您提供了成员等的访问器,但这足以显示它们是如何工作的,并打印出它打包的内容Fee、Fi、Fo 和 Fum,未指定任何行为。
The usual way of making a template do this is to use a type list:
Proper implementations of composites created from type lists give you accessors for the members and so on, but this is enough to show how they works, and prints out that it packed Fee, Fi, Fo and Fum without specifying any behaviour.
有助于实现此目的的一种可能的设计是使用复合模式。您的组件(借用维基百科绘图)是可打包的,它将实现模板Pack()方法可以做类似这样的事情:
PackImpl()是Packable中的一个纯虚方法,所有继承它的类都适当地实现了它。 GetChildren() 将返回一个 STL 容器(可能为空),用于迭代。它可以在Packable中实现,并带有一个私有成员集合来存储子对象。基本上,然后您从 Packable 继承所有类,实现 PackImpl(),然后就完成了。
请注意,如果您的继承层次结构依赖于直接作为成员的子部分,这将导致问题。如果您已经从聚合的角度解决了这个问题,那么这应该会很有效。
One possible design that would help accomplish this is to use the Composite pattern. Your Component (to borrow from the Wikipedia drawing) is Packable, which would implement a Template Method Pack() that can do something like so:
PackImpl() is a pure virtual method in Packable, and all classes that inherit implement it appropriately. GetChildren() would return an STL container (possibly empty), for iteration. It can be implemented in Packable, along with a private member collection to store the child objects. Basically, you then inherit all the classes from Packable, implement PackImpl(), and you're done.
Note that this will cause issues if your inheritance hierarchy depends on the child pieces being members directly. If you've approached the problem in terms of aggregation, this should work well.
访客模式可能会有所帮助。
http://en.wikipedia.org/wiki/Visitor_pattern
这样做的想法是将来自每个对象的处理的遍历逻辑(逐步遍历对象)。在这种情况下,每个对象的逻辑正在序列化(编码)单个对象(当然也可以反序列化)。使用普通的 OOP 技术,这应该相当简单并且重复性极低。
实现遍历和访问者模式特定的代码很烦人,但它主要是样板文件,应该是一次性的事情。
It's possible that the Visitor pattern may help.
http://en.wikipedia.org/wiki/Visitor_pattern
The idea of this is to separate the traversal logic (stepping through your objects) from the handling of each object. In this case, the per-object logic is serializing (encoding) a single object (or deserializing, of course). This should be fairly simple and minimally repetitive using normal OOP techniques.
Implementing the traversal and the Visitor-pattern specific code is annoying, but it's mostly boilerplate and should be a one-off thing.