英文:
Which design pattern to use to store streams of objects of different types to disk in go?
问题
考虑一个将不同类型的对象流保存到磁盘的函数:
func Save(fill func(c chan BaseType), file string) {}
这个函数在代码中以以下方式使用:
// 这里有不同的数据结构 data1, data2, ...
// 需要保存到磁盘
Save(
func(c chan BaseType) {
// SaveChildren1 根据 data1 数据结构生成 Child1 类型的对象
SaveChildren1(c, data1)
},
filename1)
Save(
func(c chan BaseType) {
// SaveChildren2 根据 data2 数据结构生成 Child2 类型的对象
SaveChildren2(c, data2)
},
filename2)
以此类推。有很多不同的子类型,每个子类型都需要自己的生成器函数,比如 SaveChildren1、SaveChildren2 等。这些函数实际上会填充通道(channel)中的对象。
问题是,你会如何重构这些“绑定器”——将 SaveChildren(一个带有两个参数的函数)转换为一个带有一个参数的函数?目前这段代码看起来不像是符合 Go 语言风格的良好代码。
英文:
Consider a function that saves streams of objects of different types to disk:
func Save(fill func(c chan BaseType), file string) {}
This function is used in the following way throughout the code:
// Here we've got different data structures data1, data2, ...
// that must be stored to disk
Save(
func(c chan BaseType) {
// SaveChildren1 generates objects of type Child1 based
// on the data1 data structure
SaveChildren1(c, data1)
},
filename1)
Save(
func(c chan BaseType) {
// SaveChildren2 generates objects of type Child2 based
// on the data2 data structure
SaveChildren2(c, data2)
},
filename2)
And so on. There are a lot of different child types and each requires it's own generator -- a function SaveChildren1, SaveChildren2 etc. These functions actually fill the channels with objects.
The question is how would you refactor these "binders" -- the functions that transform SaveChildren (a function of 2 args) into a function of 1 argument? Currently this code doesn't look like a well written go-style code.
答案1
得分: 3
gob包似乎是解决您问题的好方法。Go博客上有一篇很棒的文章,解释了如何以及为什么要使用gob包。以下是其中的一小段摘录:
gob包在设计时考虑了许多目标。
首先,最明显的是,它必须非常容易使用。因为Go具有反射,所以不需要单独的接口定义语言或“协议编译器”。数据结构本身就足够让该包知道如何进行编码和解码。另一方面,这种方法意味着gob在与其他语言一起使用时可能效果不佳,但这没关系:gob是面向Go的。
效率也很重要。以XML和JSON为代表的文本表示法在高效通信网络的核心位置太慢了。需要一种二进制编码。
Gob流必须是自描述的。每个从开头读取的gob流都包含足够的信息,使得完全不知道其内容的代理程序可以解析整个流。这个特性意味着,即使在很久之后,您也始终能够解码存储在文件中的gob流,即使您已经忘记了它表示的数据。
文章的后面还有一个示例,展示了gob包的易用性和多功能性。
英文:
The gob package seems like a good solution for your problem. There is a great article on the Go blog that explains how and why. A short excerpt:
> The gob package was designed with a number of goals in mind.
>
> First, and most obvious, it had to be very easy to use. First, because
> Go has reflection, there is no need for a separate interface
> definition language or "protocol compiler". The data structure itself
> is all the package should need to figure out how to encode and decode
> it. On the other hand, this approach means that gobs will never work
> as well with other languages, but that's OK: gobs are unashamedly
> Go-centric.
>
> Efficiency is also important. Textual representations, exemplified by
> XML and JSON, are too slow to put at the center of an efficient
> communications network. A binary encoding is necessary.
>
> Gob streams must be self-describing. Each gob stream, read from the
> beginning, contains sufficient information that the entire stream can
> be parsed by an agent that knows nothing a priori about its contents.
> This property means that you will always be able to decode a gob
> stream stored in a file, even long after you've forgotten what data it
> represents.
Further down the article is an example that shows how easy it is to use and how versatile it is.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论