多种输出格式的设计模式
我有一个类结构,它(在内部)表示我希望输出到文件的数据。
一些成员变量对于数据类来说是私有的,这样它就可以进行自我管理并阻止出现问题。
然后我希望将这些数据输出为多种文件格式。我可以做类似的事情,
savefile_formatA(DataClass* pDataClass, ofstream& fout);
savefile_formatB(DataClass* pDataClass, ofstream& fout);
只不过函数需要查看 DataClass 的私有成员变量。我当然可以只创建 savefile_formatXYZ()
友元函数,但随后我需要为每种不同的格式添加一个友元声明。
有没有一个标准的设计模式来解决这种事情?你会如何解决这个问题?
谢谢!
I have a class structure which represents (internally) the data I wish to output to a file.
Some of the member variables are private to the data class so that it can manage itself and stop things going awry.
I then want this data to be output into a number of file formats. I could do something like
savefile_formatA(DataClass* pDataClass, ofstream& fout);
savefile_formatB(DataClass* pDataClass, ofstream& fout);
except that the functions need to then see the private member variables of DataClass
. I could of course just make savefile_formatXYZ()
friend functions but then I would need to add a friend declaration for every different format.
Is there a standard design pattern for solving this kind of thing? How would you solve this problem?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
根据数据类的复杂性,您可能希望使用访问者模式。如果您有某种嵌套数据结构,那么 Visitor 很可能就是您所需要的。
如果格式化相对简单,例如您要对逗号分隔列表等内容进行变体,那么您可以采用这样的方法。
您的格式化程序对象都实现一个接口,例如(伪代码)
,然后数据类有一个方法
这使得被格式化的类负责选择要格式化的数据,而格式化程序负责格式的细节。
Depending upon the complexity of your data class you may wish to use a Visitor pattern. If you have some kind of nested data structure then Visitor may well be what you need.
If formatting is something relatively simple, for example you are producing variations on something such as a comma separated list then you can take an approach like this.
Your formatter objects all implement an interface such as (pseudo code)
then the data class has a method
This makes the class being formatted responsible for the choice of data to be formatted, and the formatter responsible for the details of the format.
如果您需要实现文件格式设置并从类的外部保存/加载,那么您只能使用公开可用的数据来实现。如果保存/加载需要处理非公共数据,如果重新加载类无法从公共数据重建原始非公共数据,那么必须涉及类本身或该类的友元。确实没有办法解决这个问题。
您最多能做的就是使用友元模板使编写新类型变得更容易。例如:
format
模板类型将为空类型。因此,如果您有 formatA 和 formatB,您将拥有空结构:然后,您所需要做的就是为这些格式编写专门版本的 SaveFile:
它们将自动成为 DataType 的友元。
If you need to implement file formatting and save/load from outside of the class, then you can only do it with data that is publicly available. If saving/loading needs to deal with non-public data, if reloading the class cannot reconstruct the original non-public data from public data, then either the class itself or friends of that class must be involved. There's not really a way around that.
The most you might be able to do is to make it easier to write new types, with a friend template. For example:
The
format
template type would be empty types. So if you have formatA and formatB, you would have empty structs:Then, all you need to do is write specialized versions of SaveFile for those formats:
They will automatically be friends of DataType.
通常的解决方案是决定需要导出哪些数据,
并提供对其的某种访问(可能是 getter 函数)。
从逻辑上讲,您不希望类本身必须了解任何细节
关于格式,并且您不希望格式化程序知道任何事情
更多关于类的信息而不是它必须格式化的数据。
The usual solution would be to decide what data needs to be exported,
and to provide some sort of access (probably getter functions) to it.
Logically, you don't want the class itself to have to know any details
about the formats, and you don't want the formatters to know anything
more about the class than the data it has to format.
我认为你在这里遇到的问题是设计问题之一。无论如何,序列化到文件不应该修改该数据,那么为什么这些函数应该是私有的呢?如果您所做的只是检查数据并将其写出来,那么您应该有一个足够的公共接口。
I think the problem you have here is one of design. Serializing to a file shouldn't be modifying that data in anyway, so why should those functions be private? If all you are doing is examining data and writing it out, you should have an adequate public interface.
对于您的(设计)问题,我能想到的最好的办法是一个两重解决方案:
创建从 xml 保存为您想要的任何格式的通用函数:
这样您只需为每个类创建一个序列化函数,并且还可以以任意数量的格式进行序列化。
The best thing I can think of for your (design) problem is a two fold solution:
make generic functions that save from xml to any format you want:
this way you need to make only one serializing function for each of your classes and you can also serialize in any number of formats.
您可以将其设为 DataClass 上的方法并传入流。
You would make it a method on DataClass and pass in the stream.
不要总是诉诸友元函数,因为它很容易破坏类的封装。一旦成为好友,无论您是否希望它看到,它都可以访问您的所有私人成员。
在您的情况下,您可以简单地提供一些公共接口来将必要的数据返回给客户端,然后客户端将产生不同的格式。此外,您可以看看著名的 MVC 模式
Don't always resort to friend function because it can easily break the encapsulation of your class. Once friend, it can access all your private members no matter whether you hope it see or not.
In your case, you can simply provide some public interfaces to return the necessary data to clients which will produce different formats then. Furthermore, you can take a look at famous MVC pattern if you're interested.