Вопрос дизайна слоя базы данных - PullRequest
5 голосов
/ 10 июня 2010

Я разрабатываю слой доступа к базам данных, который позволяет нам поддерживать несколько баз данных в наших программах. В конце концов, пользователи наших программ смогут выбрать базовую систему баз данных из ряда систем баз данных. Некоторые маленькие клиенты могут быть довольны MS Access, другие предпочитают MySql, другие DB2. Я хочу нацелиться на эти системы БД.

Учитывая эти требования, я создал абстрактный класс DatabaseConnection. Внутренне я использую класс System.Data.Common.Data.DbConnection, который уже дает мне некоторую гибкость.
Вещи, которым нужны конкретные экземпляры (например, OleDbCommand вместо DbCommand) скрыты в абстрактных методах, таких как CreateDbCommand (). Подклассы (например, AccessDbConnection) реализуют их и предоставляют конкретные экземпляры. В настоящее время это приводит к этой иерархии (имена классов сокращены для удобства чтения):

           DatabaseConnection
          /         |        \
 AccessConn     MySqlConn     DB2Conn

Однако есть несколько операций, специфичных для базовой системы баз данных, например, получение всех имен таблиц. Неверно помещать абстрактный метод GetTableNames () в класс DatabaseConnection и подклассы перезаписывают его.

Я подумал, что, возможно, я смогу создать другой абстрактный базовый класс с именем DatabaseTools, объявить там эти операции и затем реализовать их в подклассах, которые напоминают подклассы класса DatabaseConnection. Это означает, что для AccessDbConnection у меня также будет класс AccessTools и т. Д. И т. Д .:

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

Каким-то образом я не в восторге от этой идеи.

Какие идеи у вас есть, чтобы решить эту проблему дизайна?

Заранее спасибо за ваше время и ответы :) 1020 *

Приветствия

Christian

Ответы [ 3 ]

3 голосов
/ 10 июня 2010

Вместо абстрактного метода, почему бы не реализовать метод, который извлекает имена таблиц с использованием стандартных представлений INFORMATION_SCHEMA стандарта ANSI, а затем просто переопределяет его в реализации DatabaseConnection для поставщика, который не соответствует ANSI?

Кроме того, я не вижу ничего плохого в подходе абстрактного метода с точки зрения дизайна.

1 голос
/ 10 июня 2010

На мой взгляд, определение операций с БД в отдельной иерархии - лучшая идея. Я бы предпочел инкапсулировать инструменты внутри конкретных объектов соединений, а затем получить соединения через одну фабрику.

Точно, чтобы выполнить задачу, чтобы получить все имена таблиц, вызов будет выглядеть так:

ConnectionFactory(ACSESS).getConnection().getTools().fetchSchema();
1 голос
/ 10 июня 2010

Поскольку вы не получаете баллов за 100% чистоту ОО, следуйте советам Swingline Rage.Вы также можете сделать это чисто, просто переименовав класс; -)

Единственное, что если вы используете интерфейсы вместо абстрактных классов и наследования, у вас меньше шансов получить ожог.Интерфейсы могут наследовать друг от друга, но вам, вероятно, это не понадобится.Писать немного сложнее, но вы можете использовать их одинаково.

http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx
Интерфейс или абстрактный класс: какой использовать?

"как насчет общего кода в базовом классе?- Вы можете остаться DRY , если вы используете статические классы и вызываете их (использование некоторых процедурных приемов в ОО не грех).Вопрос № 2 в вышеприведенной теме переполнения стека выглядит интересно, но я не могу ручаться за это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...