общие конструкторы Java - PullRequest
       10

общие конструкторы Java

8 голосов
/ 08 февраля 2012

В настоящее время у меня есть следующий код, который получает данные из базы данных и затем создает User. Этот код используется во многих моих классах для создания других объектов, таких как News, Comments и т.д ...

Использует Apache Commons Dbutils.

final ResultSetHandler<User> handler = new ResultSetHandler<User>() {

            @Override
            public User handle(ResultSet rs) throws SQLException {

                User user = null;
                if (rs.next()) {
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setUsername(rs.getString("username"));
                    user.setPassword(rs.getString("password"));
                }
                return user;
            }
        };

        final User user = run.query(
                "SELECT id, username, password FROM users WHERE username = ? AND active = 2 LIMIT 1;", handler,
                username);

Можно ли обернуть QueryRunner в универсальный класс и переопределить метод запроса, чтобы обработчик создал обобщенный T с ResultSet. Я хотел бы убедиться, что любой тип T будет иметь конструктор, принимающий ResultSet.

Вот так:

        public class QueryExecuter<T> extends QueryRunner {
    private ResultSetHandler<T> _handler;

    public QueryExecuter(){//The T type was for testing haha
        super();
        handler = new ResultSetHandler<T>() {

            @Override
            public T handle(ResultSet rs) throws SQLException {

                T object = null;
                if (rs.next()) {
                    object = new T(rs);
                }
                return object;
            }
        };
    }
}

Я не знаю, поймете ли вы, но я надеюсь, спросите меня, хотите ли вы больше подробностей или лучшего объяснения.

EDIT

Я думал, что мог бы использовать AbstractClass вместо универсального типа, который расширяет все объекты различий, но кажется, что я не могу написать абстрактный конструктор. Придется ли мне создавать статический метод, который будет возвращать экземпляр объекта, например:

public abstract class DatabaseEntity {
    public static abstract DatabaseEntity create(ResultSet rs);//even this doesn't work...
}

Ответы [ 3 ]

8 голосов
/ 08 февраля 2012

Возможно, да?Но это плохая идея.

Вы можете сделать:

class ResultSetHandler<T> {
  ResultSetHandler<T>(Class<T> clazz) {
    this.clazz = clazz;
  }

  public T handle(ResultSet rs) throws SQLException {
    T object = null;
    if (rs.next()) {
      object = clazz.getConstructor(ResultSet.class).newInstance(rs)
    }
    return object;
  }
}

Однако смешивать домен и базу данных - плохая идея.Однако было бы лучше определить метод abtract, который создает объект на основе результирующего набора:

abstract class ResultSetHandler<T> {

  protected abstract T create(ResultSet rs);

  public T handle(ResultSet rs) throws SQLException {
    T object = null;
    if (rs.next()) {
      object = create(rs);
    }
    return object;
  }
}

Затем в своем реализующем классе вам нужно только предоставить метод create() вместообработки набора результатов самостоятельно, например:

h = new ResultSetHandler<Person>() {
  protected Person create(ResultSet rs) {
    return new Person(rs.getString("name"));
  }
}
3 голосов
/ 08 февраля 2012

Вы могли бы сделать что-то подобное (передав класс создаваемого объекта и использовать рефлексию для вызова его конструктора), но я бы посчитал неправильным проектировать зависимость POJO от JDBC и не только знать, как онхранится в базе данных, но также какие псевдонимы были использованы в запросе, использованном для его загрузки.

Короче говоря, конструктор POJO пользователя не несет ответственности за обработку результирующего набора внешнего неизвестного запроса.

Вы можете создать суперкласс AbstractSingleEntityHandler, который будет просто иметь

if (rs.next()) {

, и делегировал бы фактическое создание сущности абстрактному методу, но вы не получили бы много.

0 голосов
/ 08 февраля 2012

Я не думаю, что это возможно сделать на Java.Вы не можете создать экземпляр T в общем.Обобщения в java на самом деле не являются шаблонами, как в C ++, это всего лишь синтаксический сахар вокруг object, который удаляет приведение и вызывает предупреждения времени компиляции.

В C # нет способа ограничить T, поэтомучто у него должен быть конструктор.

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

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