C ++对象设计问题:高效安全地构造对象并使用数据库保存/加载

时间:2010-04-15 14:57:23

标签: c++ object

我的英语不足以解释我的问题。但我会尽我所能。

我曾经是一名Java程序员,但已经使用C ++一年多了。总是困扰我的一件事是从网络创建业务对象的策略(比如通过SNMP,Web服务或其他数据源......)并将其保存到数据库并在应用程序启动时加载它。通常我的设计如下:


class Object{
/* this is just a demonstration, in real code, there are all kinds of Object and has relationships*/
friend class DBConnection;
friend class SNMPConn
private:
    std::string& m_strName; 
    //... all kinds of properties
}

class DBConnection
{
   int load(Object& obj);
   int save(Object& obj);
   int modify(Object& obj);
   int loadAll(std::vector);
}

class SNMPConn
{
   int load(Object& obj);
   ...
}

我不赞同的是“朋友班......”的路线。它破坏了封装。我找到了一些框架,比如litesql(sourceforge.net/apps/trac/litesql)和其他商业框架,但这些框架很难与我现有的代码集成。我试图手动完成并试图找到这种工作的共同策略。

我是一名Java开发者,用C ++设计是我不擅长的。我不知道这种设计工作的最佳实践是什么。

2 个答案:

答案 0 :(得分:1)

正如我从这个问题中理解的那样(在读写DB或SNMP连接时打破封装),首先你需要一个合适的设计来消除这些“朋友”。请为连接(即IDBConnection)定义一个抽象类,也是持久对象(即IPersistent)。您可以使用“抽象工厂”模式来创建它们。此外,隔离加载并将方法保存到另一个类,并使用“访问者模式”从/向数据库初始化或保存对象。

另一点,如果您的应用程序需要嵌入式数据库,请使用SQLite,它有很多优秀的C ++包装器。希望它有所帮助

答案 1 :(得分:0)

以下是我在伪代码中的表现方式:

class Result { 
public: 
    int     getField(name); 
    string  getField(name); 
}

class Connection { 
public: 
    void save(list<pair<string, string>> properties); 
    Result query(); 
} 

class DBConnection { 
private: 
    class DBResult : public Result {  
    } 
public: 
    Result query() { 
        return ( DBResult ); 
    } 
    void save
}

class Object { 
public: 
    void load(Result); 
    void save(Connection) { 
        // make properties list 
        connection.save(properties); 
    } 
} 

如果没有Java风格的反思,那可能就是我没有进入“朋友”关系的方式。然后,您没有将连接逻辑的知识紧密地耦合到连接类中。

...

您也可以构建模板函数来执行此操作,但您仍需要朋友关系。

class Object { 
public: 
    friend template<class Conn, class Obj> load(Conn c, Obj o);
    friend template<class Conn, class Obj> save(Conn c, Obj o);
} 

load<Connection, Object>(Connection c, Object o) { 
    //access o.private to load into c 
} 

我不确定自己走哪条路。在一个方面,您将加载/保存逻辑封装在Object类中,这对于本地化非常有用,但它可能会将持久性和业务逻辑紧密地耦合在一个位置。