Главная » Spring » Устранение шаблонного кода с помощью шаблонов

0

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

К сожалению, в Java API существует масса мест, где приходится писать огромное количество шаблонного кода. Типичный пример шаблонного кода можно увидеть в приложениях, использующих JDBC для работы с базами данных. Например, если вам доводи- лось работать с JDBC прежде, вы наверняка писали нечто подобное, представленное в листинге 1.11.

Листинг 1.11. Многие Java API, такие как JDBC, требуют писать массу шаблонного кода

public Employee getEmployeeById(long id) { Connection  conn  =  null; PreparedStatement  stmt  =  null; ResultSet   rs   =   null;

try  {

conn   =   dataSource.getConnection(); stmt  =  conn.prepareStatement(

"select  id, firstname,  lastname,  salary  from  "  + "employee where id=?");             // Выбрать сотрудника

stmt.setLong(1, id);

rs = stmt.executeQuery(); Employee employee = null; if   (rs.next())   {

employee = new Employee();   // Создать объект из данных employee.setId(rs.getLong("id")); employee.setFirstName(rs.getString("firstname")); employee.setLastName(rs.getString("lastname")); employee.setSalary(rs.getBigDecimal("salary"));

}

return employee;

} catch (SQLException e) {                  // Что здесь следует сделать?

}  finally  {

if(rs !=  null) {                               // Освободить  ресурсы try  {

rs.close();

} catch(SQLException e) {}

}

if(stmt  !=  null)  { try  {

stmt.close();

} catch(SQLException e) {}

}

if(conn  !=  null)  { try  {

conn.close();

} catch(SQLException e) {}

}

}

return null;

}

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

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

Наиболее заметной особенностью листинга 1.11 является большое количество программного кода, который практически без изменений

придется писать для реализации любых операций с JDBC. Лишь малая его часть имеет прямое отношение к запросу информации, ос- новная же часть – шаблонный код обслуживания требований JDBC. JDBC – не единственный источник необходимости писать шаб- лонный код. Многие API требуют писать аналогичный шаблонный код. Операции с JMS, JNDI и со службами REST часто требуют

писать массу повторяющегося кода.

Фреймворк Spring стремится помочь в устранении шаблонного кода путем заключения его в шаблоны. Класс JdbcTemplate из фрейм- ворка Spring позволяет выполнять операции с базой данных без лишних церемоний, требуемых традиционным JDBC.

Например, с помощью класса SimpleJdbcTemplate (специализиро- ванный наследник класса JdbcTemplate, использующий преимущества особенностей Java 5) метод getEmployeeById() можно переписать так, что он окажется сосредоточен исключительно на задаче извлечения данных о работнике, а не на удовлетворении требований JDBC API. В листинге 1.12 показано, как может выглядеть обновленная версия метода getEmployeeById().

Листинг 1.12. Шаблоны позволяют сосредоточить все внимание на решении предметных задач

public Employee getEmployeeById(long id) { return jdbcTemplate.queryForObject(

"select  id,  firstname,  lastname,  salary  "  +     //  SQL-запрос "from employee where id=?",

new  RowMapper<Employee>()  {

public Employee mapRow(ResultSet rs,

int rowNum) throws SQLException {       // Отображение

Employee employee = new Employee(); // результатов в объект employee.setId(rs.getLong("id")); employee.setFirstName(rs.getString("firstname")); employee.setLastName(rs.getString("lastname")); employee.setSalary(rs.getBigDecimal("salary"));

return employee;

}

},

id);                                                              // Параметры  запроса

}

Как видите, новая версия getEmployeeById() намного проще и со- средоточена только на выборе информации из базы данных. Метод queryForObject()   шаблона  принимает  строку  SQL-запроса,  объект

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

Я показал, как фреймворк Spring борется со сложностью разработ- ки приложений на языке Java, предоставляя возможность исполь- зовать POJO, внедрение зависимостей, AOP и шаблоны. Попутно было показано, как конфигурировать компоненты и аспекты в XML- файлах. Но как загружаются эти файлы? И куда они загружаются? Познакомимся с контейнером Spring – местом, где располагаются компоненты приложения.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии