什么设计模式将数据部分保存在持久存储(SQL)中,部分保存在RAM(内存)中?

时间:2016-03-04 11:21:28

标签: c++ sql qt design-patterns memory

我正在使用C ++和Qt投射应用程序。 我在 ObjectExtended 类中的对象很少结合数据中有经常需要的数据。 每个对象都与 ObjectExtended 相关联。

示例:

 Class Object 
 {
     string importantData; //we need that very often
     int id;
 }

 Class ObjectExtended
 {
     date dateCreated; //meta info, we need this rarely
     int assosiatedObjectId; //to know to which Object this extended data relates
 }

我有对象列表list<Object>list<ObjectExtended>

我想要的是将列表保存在RAM(内存)中并将列表保存在ROM(本地存储,例如SQL)中。 需要节省内存。我已经在SQL中保存数据以保存应用程序状态和数据。

我可能遇到的问题是我的数据可能会发生变化,如果我将对象对象扩展的数据分开,我将不得不重写大量的代码。

是否有一些适合我的问题的设计模式?

2 个答案:

答案 0 :(得分:1)

将扩展保持信息放在它正在扩展的内容上而不是让对象本身持有对其可选扩展的引用可能不是那么有用。但显然已经采取了这一设计决定。

一种简单的方法是让Object保存一个指向扩展的私有指针,以及一个公共方法来获取这个指针。然后,只有在有人需要时才对该指针进行惰性求值。

class Object {
  private:
  string importantData;
  ObjectExtended *extension;

  public:
  ObjectExtended *getExtension () {
    if (extension == NULL) {
      // Load from file or database
      extension = loadFromFile (id);
    }
    return extension;
  }

您甚至可以通过将 getExtension()设为私有来进一步推动这一点,并将扩展数据的公共访问器方法添加到依次调用 getExtension 的Object。这将完全隐藏扩展数据在内存中的存在或不存在。如果内存变紧,您可以浏览对象列表并删除扩展指针,从而释放内存。

根据问题的确切性质和内存注意事项,在 Object 中保存最近/最常用的扩展数据的其他信息可能很有用,这样您就可以更好地决定什么在内存紧张时清除。

答案 1 :(得分:1)

在应用程序代码中,使用Object的虚拟getter和setter,这样如果更改Object的实现,则无需更改它。

class Object {
public:
    virtual string getA() { return ""; }
    virtual void setA(const string&) {}

    virtual string getB() { return "";  };
    virtual void setB(const string&) {}
};

然后,在PartialObject中实现继承自Object的具体数据字段:

class PartialObject {
public:
    PartialObject() : k(KeyValueStore::invalidKey()) {}
    virtual string getA() { return a;  }
    virtual void setA(const string& str) { a = str; }

protected:
    KeyValueStore::key k; // This is for persistency

private:
    string a;
};

使用其他数据字段和持久性功能实现FullObject

class FullObject : public PartialObject {
public:
    FullObject(const PartialObject& partial) {
        *this = partial; 
    }

    virtual string getB() { return b; };
    virtual void setB(const string& s) { b = s;  }

    // This function persists the full object, and returns a partial object, so that the full object can be deleted.
    PartialObject save(KeyValueStore& kvStore) {
        if (!KeyValueStore::isKeyValid(k))
            k = kvStore.generateNewKey();
        kvStore.setValue(k, serialize());
        return PartialObject(reinterpret_cast<PartialObject&>(*this));
    }

    void load(KeyValueStore& kvStore) {
        deseriaize(kvStore.getValue(k));
    }
private:
    string serialize() {
        // Here you should implement the code for serializing all fields, and return serialized data as string.
    }
    void deseriaize(const string& str) {
        // Here you should set "this" to the deserialized version of str.
    }
private: 
    string b;
};

班级KeyValueStore是数据访问层:

class KeyValueStore {
public:
    typedef unsigned long key;

    string getValue(unsigned long long key);
    void setValue(unsigned long long key, const string& value);

    static bool isKeyValid(key k) { return k > 0; }
    static key invalidKey() { return 0; }
    key generateNewKey();
};
相关问题