面向对象或模块化文件和数据I/O的技术?

drm*_*elr 8 oop io design-patterns modularity

似乎每次我编写任何处理提取,推送,读取或写入操作的代码时,整个代码段都是临时的,丑陋的,并且在该确切应用程序的上下文之外完全无法使用.更糟糕的是,每当我设计这些东西时,我都必须重新发明轮子.在我看来,I/O操作的本质是非常线性的,并不适合模块化或面向对象的模式.

我真的希望有人能告诉我这里错了.是否存在面向对象或模块化文件和数据I/O的技术/模式?我可以遵循一些约定来添加一些代码重用性吗?我知道存在各种工具来简化单个文件的读取,比如XML解析器等,但我指的是使用这些工具的较大设计.

问题不仅限于单一语言; 我在Java,C,Matlab,Python和其他人中遇到过同样的问题.

这个问题的子主题是关于什么对象应该调用保存的问题.这个问题似乎是指工厂模式,其中文件的内容被构建,然后最终写入磁盘.我的问题是关于整体架构,包括用于写操作的工厂,还有用于读取/获取操作的(Insert Pattern Here).

我能想到的最好的东西是外立面图案......但圣洁的烟雾是那些丑陋的立面的代码.

有人请告诉我一个模式,我可以重新使用我的一些代码,或者至少遵循一个模板用于将来的读写.

有人在这里询问模块化设计,但答案是针对该提问者的问题,并不是完全有用的.


这只是一个例子,它基于我去年做的一个项目.随意提供一个不同的例子.

我们的程序是一个物理沙箱.我们想要加载描述该沙箱中对象的物理属性的XML数据.我们还需要加载包含3D渲染信息的.3DS文件.最后,我们需要查询SQL数据库以找出谁拥有哪些对象.

我们还需要能够支持3D模型格式.我们还不知道那些文件会是什么样子,但我们希望提前设置代码框架.这样,一旦我们获得新的数据模式,就可以快速实现加载例程.

来自所有3个来源的数据将用于在我们的软件中创建对象的实例.

之后,我们需要将物理信息(如位置和速度)保存到数据库,并将自定义纹理信息保存到本地文件.我们不知道纹理的文件类型是什么,所以我们只想布置代码结构,以便我们以后可以输入保存代码.

如果没有某种设计模式,即使是少量的对象也会迅速导致紧密耦合的网络.

没有模式网络

外观可以将对象/数据与相应的文件分离,但所有这一切都将问题集中在输入和输出外观中,这可能会在匆忙中变成一场噩梦般的混乱.此外,对象/数据现在与立面紧密耦合,因此实际上没有获得模块化.

门面网络


从3周前编辑...

以前,我提出了一堆伪问题来解决我第一次提出这个问题时遇到的问题,但我已经决定它混淆了我的主要问题.我只想说:我必须在这个特定的读取操作集中使用大约2000行真正不稳定的代码,它在处理和组织方面做得非常少,而且我再也无法在另一个项目上使用它了.

我想避免将来编写这样的代码.

Sil*_*gel 3

此解决方案可能无法完全解决您的问题或问题的某些细节,但我想分享我为统一 I/O 操作所采取的方法。我之前在几种不同的高级语言中使用过它。当与序列化结合使用时,该策略的扩展效果最佳。

看来两个基本的 I/O 操作是 Save/Put 和 Load/Get。这是最抽象的通用接口,它表示:

public interface ObjectRepository
{
    <T> void save(string resourceId, T obj);
    <T> T load(string resourceId);
}
Run Code Online (Sandbox Code Playgroud)

此策略足以满足所有类型的 I/O 操作,其中资源 ID(数据库 UUID/GUID/字符串、文件路径、Web URL...等)已知。

最简单的实现根据语言和框架的不同而有所不同,但我发现最普遍适用的是依赖于标准序列化形式的实现,即二进制、XML 和 JSON。使用专有对象时,我最常使用 XmlFileRepository,它将我的简单数据对象与 Xml 相互转换,并在所选文件路径中保存/加载。

此外,如果与抽象工厂模式结合使用,即使对于单一类型的对象使用不同的数据格式输入和输出也是相当简单的。示例代码:

public NewtonianObject load(string respositoryType, string resourceId) 
{
    ObjectRepository repo = RepositoryFactory.create(respositoryType);
    return (NewtonianObject)repo.load(resourceId);
}

public void exportAsXml(string fileName, NewtonianObject obj)
{
    ObjectRepository repo = RepositoryFactory.create("XmlFileRepository");
    repo.save(fileName, obj);
}
Run Code Online (Sandbox Code Playgroud)