2010-06-10 179 views
5

我一直在设计一个数据库访问层,它允许我们在我们的程序中支持多个数据库。最后,我们程序的用户应能够从一系列数据库系统中选择底层数据库系统。一些小客户可能对MS Access感到满意,其他人则更喜欢MySql和其他DB2。那些数据库系统是我现在想要的目标。数据库层设计问题

鉴于这些要求,我想出了一个抽象类DatabaseConnection。在内部,我使用System.Data.Common.Data.DbConnection类,这已经给了我相当大的灵活性。
需要具体实例(OleDbCommand而不是DbCommand)的事物隐藏在像CreateDbCommand()这样的抽象方法中。子类(如AccessDbConnection)实现这些并提供具体实例。目前,导致这个层次结构(简称为便于阅读,类名):

  DatabaseConnection 
     /  |  \ 
AccessConn  MySqlConn  DB2Conn 

不过,也有一些操作所特有的底层数据库系统,如检索所有的表名。将一个抽象方法GetTableNames()放入DatabaseConnection-class并让子类覆盖它是不对的。

我想也许我可以创建另一个名为DatabaseTools的抽象基类,在那里声明那些操作,然后在类似DatabaseConnection类的子类的子类中实现它们。这意味着对于一个AccessDbConnection,我也想有一个类AccessTools等等等等:

  DatabaseConnection      DatabaseTools 
     /  |  \     /  |  \ 
AccessConn  MySqlConn  DB2Conn AccessTools MySqlTools DB2Tools 

不知怎的,我真的不被这个想法激动不已。

你有什么想法来解决这个设计问题?

预先感谢您的时间和答案:)

干杯

基督教

+0

令人担心你关于设计的?这对我来说似乎是合理的(乍一看)。我想包含一些方法来确保你不能在'MySQLConn'上使用'AccessTools',但这是我能想到的唯一的方法。 – ChrisF 2010-06-10 10:45:42

+0

我认为抽象方法很好。你能给出什么有力的理由来违反奥卡姆剃刀和KISS原则,并创造出第二套足够好的课程?我已经使用了您在六个项目中描述的第一个架构,并且从来没有遇到任何问题。如果你坚持使用标准的SQL,那么只需要很少的特定于DB的代码即可。 – 2010-06-10 10:56:44

+0

@ChrisF:当我想到一个DatabaseConnection类时,我仅仅把它看作是连接本身,它使我能够创建,打开和关闭连接。查询所有的表名和其他数据库系统的具体操作必须对连接做些事情(毕竟,它们是对它进行操作的),但我觉得它们不应该太紧密地连接到连接上。 – Christian 2010-06-10 10:57:28

回答

1

由于您没有得到纯度100%的点数,请遵循Swingline Rage的建议。你也可以通过重命名这个类来使它变得纯粹;-)

唯一的问题是,如果你使用接口而不是抽象类和继承,你不太可能被烧毁。接口可以相互继承,但你可能不需要它。有点难写,但你可以用同样的方式使用它们。

http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx
Interface or an Abstract Class: which one to use?

“关于在基类共享代码是什么?” - 如果您使用静态类并调用它们,您可以保留DRY(在OO中使用某些过程技术并不是一项罪过)。在上面的堆栈溢出主题Q#2看起来很有趣,但我不能担保。

3

不是一个抽象方法,为什么不实现一个检索使用ANSI标准INFORMATION_SCHEMA意见表名,然后在不符合ANSI标准的供应商的DatabaseConnection实施中覆盖它?

除此之外,从设计的角度来看,我没有发现抽象方法的任何问题。

1

在我看来,在单独的层次结构中定义数据库操作是一个更好的想法。 我宁愿将这些工具封装在具体连接对象中,然后通过一个工厂获取连接。

准确地说,执行任务中获得所有的表名,调用将是这样的:

ConnectionFactory(ACSESS).getConnection().getTools().fetchSchema();