c++ - 更好地设计具有继承性的 Db 抽象

标签 c++ inheritance design-patterns multiple-inheritance

我的应用程序处理不同类型的消息并将它们存储在数据库中。现在我使用了以下设计:

数据库类:

class DbObject
{
public:
    // read/write object members from/to DB 
    virtual void readFromDb() = 0;
    virtual void writeToDb() = 0;

    // Other stuff, db connection etc.
    void doDbStuff();
}

消息的基类:

class BaseMsg
{
public:
    // read/write object members from/to DB 
    virtual std::string toXml() = 0;
    virtual void fromXml(const & std::string s) = 0;
}

消息类型 A、B 等

class MsgA : public BaseMsg, DbObject
{
public:
    std::string toXml();
    void fromXml(const & std::string s);

    void readFromDb();
    void writeToDb();
}

这种设计效果很好,每条处理过的消息都有它自己的对象,可以写入 XML,从 XML 读取,存储和读取消息特定内容的数据库(在 MsgA 中实现)。

但是,目前我们正在考虑将应用程序移植到新平台,当前数据库不可用,因此我们将使用其他数据库类型。

通常我现在会有一个用于数据库访问的基类和每个数据库类型的子类。但是目前的设计是不可能的,因为我不想有一个 MsgADatabase1 类和一个 MsgADatabase2 类等。

是否有任何设计模式,我可以原则上保留我当前的设计,但将当前使用的数据库类型隐藏在某种抽象层后面?

最佳答案

<强>1。首先想到的是DbOject作为适配器。

根据四人帮的说法, adapter 应通过多重继承或组合为适配对象(具体数据库对象)提供目标接口(interface)。

在您的多重继承的上下文中,此设计将对每个 DbObject 强加您在消息中继承,它的构造函数将创建与 DB 特定对象的一对一链接。但是构造函数怎么知道要创建哪个具体的数据库类呢?

<强>2。接下来的想法:将此适配器与抽象工厂结合起来

创建实例化抽象数据库独立对象的具体数据库相关对象的最自然模式是使用 abstract factory

结合适配器,你会遇到以下场景:

  • 在启动时,一个虚拟工厂(类 Database)对象被具体数据库相关工厂(class DatabaseBrandA : public Database)实例化
  • 虚拟工厂提供了创建DbIndependentObject的功能.具体工厂实现此功能,提供自己的具体对象(class DbBrandAdependentObject : public DbIndependentObject)
  • 每次创建消息时,基DbObject适配器请求虚拟工厂实例化一个新对象。所以它指的是DbIndependentObjectDbBrandAdependentObject 实现)

但是,我不知道你的DbObject的内容是不是真的非常丰富,它需要与数据库特定对象的一对一关系。如此复杂的模式在这里不是矫枉过正吗?

3.最终结论:适配器结合代理设计模式

我怀疑你的DbObject只是作为获取由派生消息对象实现的虚拟读写功能的便捷方式,可以在需要数据库交互时调用。

如果您当前的代码设计为 DbOject封装了与数据库相关的所有内容,您只需要一个 proxy 到这个数据库。

这将根据以下场景工作:

  • 在启动时,一个抽象数据库(类 Database)对象被实例化为一个具体的数据库(class DatabaseBrandA : public Database)
  • 每次创建消息时,基DbObject充当引用数据库对象的代理。
  • 每次需要执行数据库操作时,DbObject通过提供所需的读写功能充当消息的适配器。

关于c++ - 更好地设计具有继承性的 Db 抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27213176/

相关文章:

java - 多态性和接口(interface) - 澄清?

c++ - 在 rapidjson 上,只将数字编码为字符串,然后对其进行解码

python - Python 中关于多重继承的怪癖!至少我是这么认为的

php - 在 PHP 中,是否可以使用字符串设置变量名?

java - JAXB 无法识别类型继承

ios - Objective C 中的属性继承

ios - UIKit 背后的设计模式

C++ 更改打印队列所有者

c++ - boolean 冒号初始化

c++ - 虚拟派生的多态类的大小