2013-04-15 106 views
0

我正在设计一个数据库浏览应用程序,该应用程序到目前为止都支持MySQL,但最近我也开始实施支持Sqlite,并且在设计连接体系结构的方式时,我面临一些丑陋。这只是关于“连接”部分(即:你得到的用户/数据库/主机,或为sqlite的文件名),而不是数据库功能。这已经被整理出来了。关于数据库连接体系结构的设计难题

我有一个基类“连接”暴露“正常”的方法,如name(),或它们是等virtual string fullLocation() = 0返回箱,可用于识别数据库(例如字符串纯虚拟方法:[email protected]限于MySQL,或者Sqlite的/etc/mydb.sqlite)。

现在,用户当然需要指定他想连接的数据库,所以在应用程序的GUI中,他只需选择类型,然后填入凭证。在这里,我的麻烦开始了。我创建了一个MySqlConnectionSqliteConnection类,无论从Connection衍生而来,但大部分我结束了类似的情况:

 Connection* c = 0; 
     if(gui->engine_name() == "MYSQL") 
     { 
      string host = gui->getHost(); 
      string user = gui->getUser(); 
      string password = gui->getPassword(); 
      int port = gui->getPort(); 
      string db = gui->getDatabase(); 
      c = new MySqlConnection(host, user, password, db, port); 
     } 
     else 
     { 
      string dbFile = gui->getSqliteDbFile(); 
      c = new SqliteConnection(dbFile); 
     } 
     string meta = application->use_connection(&c); 

,我有恐惧,这将持续到整个应用程序,由于这两个数据库引擎的性质如此不同。

你有一些关于如何以优雅的方式解决这个问题的指导?

+0

封装什么变化,封装什么保持不变。 –

+0

@PeterWood正是我所做的,但在这种情况下唯一保持不变的是连接的“名称”......即使连接方法不同(用户/密码/主机与文件名:)) – fritzone

+0

另一种选择是有一个工厂,创建'连接'对象,所以差异只在施工期间相关 –

回答

0

一个更优雅的方式将设计一个工厂类,并在工厂的GenerateConnection()方法处理GUI输入:

void ConnectionFactory::GenerateConnection(Connection* c) 
{ 
if(gui->engine_name() == "MYSQL") 
    { 
     string host = gui->getHost(); 
     string user = gui->getUser(); 
     string password = gui->getPassword(); 
     int port = gui->getPort(); 
     string db = gui->getDatabase(); 
     c = new MySqlConnection(host, user, password, db, port); 
    } 
    else 
    { 
     string dbFile = gui->getSqliteDbFile(); 
     c = new SqliteConnection(dbFile); 
    } 

} 

如果你不喜欢在GUI上的依赖,你可以定义一个struct命名为Parameters并根据gui输入更新其实例,并将该对象赋予连接工厂的连接生成方法。

+0

我宁愿没有工厂了解的GUI自从现在我使用Qt,如果我决定切换到GTK,我将在“核心”中拥有这种依赖关系... – fritzone

+0

@fritzone然后,您可以将相关变量保存在一个结构对象中,并根据此对象的内容采取行动 –

0

您需要Pattern Factory,它会以抽象的方式为您创建Connection。这是肤浅的答案。 这个工厂将是很好的与Builder模式参数化。类似的东西:

ParamBuilder *b = new ParamBuilder; 
if(gui->engine_name() == "MYSQL") 
{ 
     b->setHost(gui->getHost()) 
     ->setUser(gui->getUser()); 
     ->setPassword(gui->getPassword()); 
     ... 
    } 
    else 
    { 
     b->setFile(gui->getSqliteDbFile()); 
    } 
    Connection *c = globalConnectionFactory->createConnection(b);