【问题标题】:Database module abstract (independent) from other modules of the game数据库模块抽象(独立)于游戏的其他模块
【发布时间】:2012-12-04 22:10:21
【问题描述】:

我有一个由几个模块组成的游戏。

其中之一是数据库模块。 我想把它变成这样:

Database{
    public:
        save(&Object); //all my classes in the all modules inherit from Object
        load(&Object);
};

使该模块独立于其他模块的最佳方法是什么(其他模块将使用saveload函数将数据存储在Database中)?

我考虑了几个解决方案:

  1. 所有对象都有类似serialize() 的方法,该方法继承自Object 类(类似于Java)。 Database 使用该方法获取字符串并保存。明显的缺点是:所有对象都必须实现新方法,并且保存字符串不是最佳选择(不知道类的结构)。
  2. 为所有类制作“清单”(例如,在将发送到Database 的文本文件中)。该清单将描述类的结构是什么(例如,一个字符串、两个双精度、一个罕见使用的 int)。缺点是灵活性 - 更改其他模块中的类会影响清单。
  3. 所有类都有自己的saveload 方法,Database 使用它们。我不想要它,因为所有类都必须知道数据库类型,saveload 应该在 Database 类中,而不是分布在整个代码中(这是制作这样一个模块的重点) .
  4. Database 知道所有其他模块(并且会知道如何保存所有对象)。这里的坏事是很多依赖。任何模块的更改都会影响Database

哪种方式好?或者也许有更好的选择?

【问题讨论】:

  • 当您谈论 serialize() 方法时,听起来您想使用名称值存储(ala NoSQL)。通常,数据库会在表中的每列存储一个值。

标签: c++ database module dependencies


【解决方案1】:

我遇到的一个解决方案是让所有 Object 子类实现 virtual void serialize(ISerializer& serializer) 方法。

ISerializer 将具有纯虚方法,如 void onInt(int value)void onString(const char* string) 等,由其 serialize() 方法中的 Object 子类调用。您的数据库模块可以在两个单独的类中实现 ISerializerDatabaseReaderDatabaseWriter。稍后您可以添加同样实现 ISerializerObjectInspectionFileDumperOnScreenObjectStateDebuggerNetworkWriter,但在其他模块中。每个对象只需要实现一次serialize()-方法即可获得所有这些扩展可能性。

优点:

  • 只要您不为旧版本的对象读取数据,而顶部没有某种版本控制方案,则几乎可以保证读取和写入匹配。
  • 这是一种正交设计,其中 Object 类型和 Serializer 类型的数量可以相互独立地增长。

缺点:

  • 主要是一些虚函数开销,如果这对您的项目来说是个问题。不过,这并不是您在常规游戏中通常会做的事情。

稍后,您可能会遇到不想序列化的对象,然后将其分离到 ISerializable 接口类中,只包含纯虚拟serialize()-方法。为了适应重要的序列化程序(如调试序列化程序),您可能需要改为 void onInt(const char* name, int value) 等。

HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-12
    • 2021-11-09
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多