ООП-программирование с доступом к базе данных

Я работаю над проектом с доступом к базе данных. Вот схема классов, которые я реализовал

public class Foo {

    private String id;
    private String name;
    private int x;
    private String y;
    private String z;
    ...

    public Foo(String id) throws SQLException {
       this.id=id;
       try (Statement stmt = MyConnectionManager().getConnection().createStatement()) {
          ResultSet rs = stmt.executeQuery("SELECT * FROM " + TABLE_NAME
                + " WHERE(id='" + this.id + "')");
          if (!rs.next()) {
             throw new NoExistException();
          }
          this.name = rs.getString("Name");
          this.x = ...
          ...
       } catch (SQLException ex) {
          throw ex;
       }
    }
    public int getId() {
       return this.id;
    }

    public String getName() {
    .
    .
    .

Но когда я посмотрел на большинство примеров oop, я обнаружил, что большинство людей используют дополнительный класс для доступа к базе данных. Я не знаю, что я собираюсь сказать, это ошибка. Эти коды обращаются к базе данных для инициализации каждой переменной-члена. Но в моем коде база данных доступна только один раз для инициализации моего объекта. Должен ли я изменить этот подход. Если я изменю это повлияет на скорость моего приложения, когда оно хочет инициализировать больше объектов вместе (может быть сотни). Я думаю, что это может быть вопрос о дублировании. Но я не нашел удовлетворительного ответа для моей конкретной проблемы.


person Jasir    schedule 01.05.2013    source источник
comment
Вы отметили свой вопрос как «трехуровневый», это правда: вам нужно поместить доступ к базе данных на выделенный уровень.   -  person Aubin    schedule 01.05.2013


Ответы (2)


Ваш подход нарушает принцип единой ответственности и Разделение интересов — в основном класс не должен быть одновременно классом предметной области и иметь доступ к базе данных.

Подход, при котором каждая переменная-член инициализируется независимо, и эта инициализация включает вызов базы данных, еще хуже и также не будет работать, а также нарушает ранее упомянутое принцип единой ответственности и разделение ответственности просто не будет выполнять.

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

В вашем случае это означает, что вы получите интерфейс DAO, который может выглядеть примерно так: :

public interface FooDao
{
  public Collection<Foo> getAll() throws DaoException;

  public Foo getByIdentity(String id) throws DaoException;

  public Collection<Foo> getByName(String name) throws DaoException;

  public void save(Collection<Foo> foos) throws DaoException;
}

Интерфейс может иметь ряд методов получения или предоставлять какой-либо механизм, основанный на критериях, позволяющий создавать более сложные запросы (некоторое время назад я написал код, который делает это здесь), но важно то, что именно этот интерфейс использует весь ваш код. Затем вы реализуете этот интерфейс по своему усмотрению (используя прямой JDBC, если ваша объектная модель проста, или Hibernate, если вам нужно что-то более продвинутое) или имитируйте его в своих модульных тестах.

Когда вы вводите класс Bar, вы повторяете шаблон, определяющий BarDao и реализующий по мере необходимости снова.

person Nick Holt    schedule 01.05.2013
comment
Большое спасибо за ваш отличный ответ. Должен ли я создать экземпляр всего класса сразу из уровня доступа к базе данных. У меня много доменных классов. Должен ли я создавать отдельные функции на уровне базы данных для инициализации каждого класса - person Jasir; 01.05.2013
comment
@Jaz - я расширю свой ответ - person Nick Holt; 01.05.2013
comment
Большое спасибо. Я решил изменить шаблон своего кода. Теперь я знаю, что такое DAO. Я видел несколько примеров на tutorialspoint. Еще раз спасибо - person Jasir; 01.05.2013

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

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

person Hamid    schedule 01.05.2013