Шаблоны проектирования «банды четырёх (GoF)»
Паттернами проектирования (Design Patterns) называют решения часто встречающихся проблем в области разработки программного обеспечения. В данном случае предполагается, что есть некоторый набор общих формализованных проблем, которые довольно часто встречаются, и паттерны предоставляют ряд принципов для решения этих проблем.
Концепцию паттернов впервые описал Кристофер Александер в книге «Язык шаблонов. Города. Здания. Строительство».
Идея показалась привлекательной авторам Эриху Гамму, Ричарду Хелму, Ральфу Джонсону и Джону Влиссидесу, их принято называть «бандой четырёх» (Gang of Four). В 1995 году они написали книгу «Design Patterns: Elements of Reusable Object-Oriented Software», в которой применили концепцию типовых паттернов в программировании. В книгу вошли 23 паттерна, решающие различные проблемы объектно-ориентированного дизайна.
Зачем знать паттерны?
Самое главная причина — паттерны упрощают проектирование и поддержку программ.
Проверенные решения.
Ваш код более предсказуем когда вы используете готовые решения, вместо повторного изобретения велосипеда.
Стандартизация кода.
Вы делаете меньше ошибок, так как используете типовые унифицированные решения, в которых давно найдены все скрытые проблемы.
Общий язык.
Вы произносите название паттерна, вместо того, чтобы час объяснять другим членам команды какой подход вы придумали и какие классы для этого нужны.
Каталог шаблонов проектирования
Порождающие паттерны:
Порождающие паттерны — это паттерны, которые абстрагируют процесс инстанцирования или, иными словами, процесс порождения классов и объектов. Среди них выделяются следующие:
Абстрактная фабрика (Abstract Factory)
Строитель (Builder)
Фабричный метод (Factory Method)
Прототип (Prototype)
Одиночка (Singleton)
Структурные паттерны:
Структурные паттерны — рассматривает, как классы и объекты образуют более крупные структуры — более сложные по характеру классы и объекты. К таким шаблонам относятся:
Адаптер (Adapter)
Мост (Bridge)
Компоновщик (Composite)
Декоратор (Decorator)
Фасад (Facade)
Приспособленец (Flyweight)
Заместитель (Proxy)
Поведенческие паттерны:
Поведенческие паттерны — они определяют алгоритмы и взаимодействие между классами и объектами, то есть их поведение. Среди подобных шаблонов можно выделить следующие:
Паттерн Data Access Object
Способ доступа к данным бывает разным и зависит от источника данных. Способ доступа к персистентному хранилищу, например к базе данных, очень зависит от типа этого хранилища (реляционные базы данных, объектно-ориентированные базы данных, однородные или «плоские» файлы и т.д.) и от конкретной реализации.
2 Проблема
Многие реальные приложения платформы Java 2 Platform, Enterprise Edition (J2EE) должны использовать на некотором этапе персистентные данные. Для этих приложений персистентное хранение реализуется различными механизмами и существуют значительные отличия в API, используемых для доступа к этим механизмам. Другим приложениям может понадобиться доступ к данным, расположенным на разных системах. Например, данные могут находиться на мэйнфреймах, LDAP-репозиториях (Lightweight Directory Access Protocol — облегченный протокол доступа к каталогам) и т.д. Другим примером является ситуация, когда данные предоставляются службами, выполняющимися на разных внешних системах, таких как системы business-to-business (B2B), системы обслуживания кредитных карт и др.
Обычно приложения совместно используют распределенные компоненты для представления персистентных данных, например, компоненты управления данными. Считается, что приложение использует управляемую компонентом персистенцию (BMP- bean-managed persistence) для своих компонентов управления данными, если эти компоненты явно обращаются к персистентным данным — то есть компонент содержит код прямого доступа к хранилищу данных. Приложение с более простыми требованиями может вместо компонентов управления данными использовать сессионные компоненты или сервлеты с прямым доступом к хранилищу данных для извлечения и изменения данных. Также, приложение могло бы использовать компоненты управления данными с управляемой контейнером персистенцией, передавая, таким образом, контейнеру функции управления транзакциями и деталями персистенции.
Для доступа к данным, расположенным в системе управления реляционными базами данных (RDBMS), приложения могут использовать JDBC API. JDBC API предоставляет стандартный механизм доступа и управления данными в персистентном хранилище, таком как реляционная база данных. JDBC API позволяет в J2EE-приложениях использовать SQL-команды, являющиеся стандартным средством доступа к RDBMS-таблицам. Однако, даже внутри среды RDBMS фактический синтаксис и формат SQL-команд может сильно зависеть от конкретной базы данных.
Для различных типов персистентных хранилищ существует еще большее число вариантов. Механизмы доступа, поддерживаемые API и функции отличаются для различных типов персистентных хранилищ, таких как RDBMS, объектно-ориентированные базы данных, плоские файлы и т.д. Приложения, которым нужен доступ к данным, расположенным на традиционных или несовместимых системах (например, мэйнфреймы или B2B-службы), часто вынуждены использовать патентованные API. Такие источники данных представляют проблему для приложений и могут потенциально создавать прямую зависимость между кодом приложения и кодом доступа к данным. Когда бизнес-компонентам (компонентам управления данными, сессионным компонентам и даже презентационным компонентам, таким как сервлеты и вспомогательные объекты для JSP-страниц) необходим доступ к источнику данных, они могут использовать соответствующий API для получения соединения и управления этим источником данных. Но включение кода для установления соединения и доступа к данным в код этих компонентов создает тесную связь между компонентами и реализацией источника данных. Такая зависимость кода в компонентах может сделать миграцию приложения от одного типа источника данных к другому трудной и громоздкой. При изменениях источника данных компоненты необходимо изменить.
3 Ограничения
- Компоненты управления данными с управляемой компонентом персистенцией, сессионные компоненты, сервлеты и другие объекты, такие как вспомогательные объекты для JSP-страниц, должны получать и сохранять информацию в персистентных хранилищах и других источниках данных, например традиционных системах, B2B, LDAP и т.д.
- API доступа к персистентному хранилищу данных может зависеть от поставщика продукта. Другие источники данных могут иметь нестандартные или патентованные API. Эти API и их возможности зависят от типа хранилища данных — RDBMS, система управления объектно-ориентированными базами данных (OODBMS), XML-документы, плоские файлы и т.д. Унифицированный API доступа к этим несовместимым системам отсутствует.
- Для извлечения или сохранения данных во внешних и/или традиционных системах компоненты обычно используют патентованные API.
- Включение в компоненты специфических механизмов доступа и API прямо влияет на переносимость компонентов.
- Компоненты должны быть прозрачны для реальной реализации персистентного хранилища или источника данных и обеспечивать легкую миграцию на продукт другого поставщика, на другой тип хранилища и на другой тип источника данных.
4 Решение
Используйте Data Access Object (DAO) для абстрагирования и инкапсулирования доступа к источнику данных. DAO управляет соединением с источником данных для получения и записи данных.
DAO реализует необходимый для работы с источником данных механизм доступа. Источником данных может быть персистентное хранилище (например, RDBMS), внешняя служба (например, B2B-биржа), репозиторий (LDAP-база данных), или бизнес-служба, обращение к которой осуществляется при помощи протокола CORBA Internet Inter-ORB Protocol (IIOP) или низкоуровневых сокетов. Использующие DAO бизнес-компоненты работают с более простым интерфейсом, предоставляемым объектом DAO своим клиентам. DAO полностью скрывает детали реализации источника данных от клиентов. Поскольку при изменениях реализации источника данных представляемый DAO интерфейс не изменяется, этот паттерн дает возможность DAO принимать различные схемы хранилищ без влияния на клиенты или бизнес-компоненты. По существу, DAO выполняет функцию адаптера между компонентом и источником данных.
4.1 Структура
На рисунке 9.1 показана диаграмма классов, представляющая взаимоотношения в паттерне DAO.
Рисунок 9.1 Data Access Object
4.2 Участники и обязанности
На рисунке 9.2 представлена диаграмма последовательности действий, показывающая взаимодействия между различными участниками в данном паттерне.
Рисунок 9.2 Диаграмма последовательности действий паттерна Data Access Object
4.2.1 BusinessObject
BusinessObject представляет клиента данных. Это объект, который нуждается в доступе к источнику данных для получения и сохранения данных. BusinessObject может быть реализован как сессионный компонент, компонент управления данными или другой Java-объект, сервлет или вспомогательный компонент.
4.2.2 DataAccessObject
DataAccessObject является первичным объектом данного паттерна. DataAccessObject абстрагирует используемую реализацию доступа к данным для BusinessObject, обеспечивая прозрачный доступ к источнику данных. BusinessObject передает также ответственность за выполнение операций загрузки и сохранения данных объекту DataAccessObject.
4.2.3 DataSource
Представляет реализацию источника данных. Источником данных может быть база данных, например, RDBMS, OODBMS, XML-репозиторий, система плоских файлов и др. Источником данных может быть также другая система (традиционная/мэйнфрейм), служба (B2B-служба или система обслуживания кредитных карт), или какой-либо репозиторий (LDAP).
4.2.4 TransferObject
Представляет собой Transfer Object, используемый для передачи данных. DataAccessObject может использовать Transfer Object для возврата данных клиенту. DataAccessObject может также принимать данные от клиента в объекте Transfer Object для их обновления в источнике данных.
4.3 Стратегии
4.3.1 Стратегия Automatic DAO Code Generation
Поскольку BusinessObject соответствует конкретному DAO, есть возможность установить взаимоотношения между BusinessObject, DAO, и применяемыми реализациями (таблицы в RDBMS). После установления взаимоотношений появляется возможность написать простую утилиту для генерации кода, зависящую от приложения, которая может генерировать код для всех нужных приложению объектов DAO. Метаданные для генерации DAO могут определяться разработчиком в файле-дескрипторе. В качестве альтернативы генератор кода может автоматически проанализировать базу данных и предоставить необходимые для доступа к ней объекты DAO. Если требования к DAO являются достаточно сложными, можно использовать интсрументальные средства сторонних производителей, обеспечивающие отображение «объектный-реляционный» для баз данных RDBMS. Такие средства обычно имеют GUI-интерфейс для отображения бизнес-объектов в объекты персистентного хранилища и определяют промежуточные объекты DAO. Инструментальные средства автоматически генерируют код после завершения отображения и могут предоставлять другие ценные функции, например, кэширование результатов, кэширование запросов, интеграция с серверами приложений, интеграция с другими сторонними продуктами (например, распределенное кэширование) и т.д.
4.3.2 Стратегия Factory for Data Access Objects
Паттерн DAO может быть сделан очень гибким при использовании паттернов Abstract Factory [GoF] и Factory Method [GoF] (см. секцию «Связанные паттерны» в этом разделе).
Данная стратегия может быть реализована с использованием паттерна Factory Method для генерации нескольких объектов DAO, которые нужны приложению, в тех случаях, когда применяемое хранилище данных не изменяется при переходе от одной реализации к другой. Диаграмма классов этого случая приведена на рисунке 9.3.
Рисунок 9.3 Стратегия Factory for Data Access Object, использующая Factory Method
Когда используемое хранилище данных может измениться при переходе от одной реализации к другой, данная стратегия может быть реализована с применением паттерна Abstract Factory. Abstract Factory, в свою очередь, может создать и использовать реализацию Factory Method implementation, как рекомендуется в книге «Паттерны проектирования: Элементы повторно используемого объектно-ориентированного программного обеспечения» [GoF]. В этом случае данная стратегия предоставляет абстрактный объект генератора DAO (Abstract Factory), который может создавать конкретные генераторы DAO различного типа, причем каждый генератор может поддерживать различные типы реализаций персистентных хранилищ данных. После получения конкретного генератора для конкретной реализации вы можете использовать его для генерации объектов DAO, поддерживаемых и реализуемых в этой реализации.
Диаграмма классов этой стратегии представлена на рисунке 9.4. Эта диаграмма классов показывает базовый генератор DAO, являющийся абстрактным классом, который наследуется и реализуется различными конкретными генераторами DAO для поддержки доступа к специфической реализации хранилища данных. Клиент может получить реализацию конкретного генератора DAO, например RdbDAOFactory, и использовать его для получения конкретных объектов DAO, работающих с этой конкретной реализацией хранилища данных. Например, клиент может получить RdbDAOFactory и использовать его для получения конкретных DAO, таких как RdbCustomerDAO, RdbAccountDAO и др. Объекты DAO могут расширять и реализовывать общий базовый класс (показанные как DAO1 и DAO2) и детально описывать требования к DAO для поддерживаемых бизнес-объектов. Каждый конкретный объект DAO отвечает за соединение с источником данных и за получение и управление данными для поддерживаемого им бизнес-объекта.
Пример реализации паттерна DAO и его стратегий приведен в секции «Пример» данного раздела.
Рисунок 9.4 Стратегия Factory for Data Access Object, использующая Abstract Factory
Диаграмма последовательности действий, описывающая взаимодействия для этой стратегии, представлена на рисунке 9.5.
Рисунок 9.5 Диаграмма последовательности действий для стратегии Factory for Data Access Objects, использующей Abstract Factory
5 Выводы
- Разрешает прозрачность Бизнес-объекты могут использовать источник данных, не имея знаний о конкретных деталях его реализации. Доступ является прозрачным, поскольку детали реализации скрыты внутри DAO.
- Облегчает миграцию Уровень объектов DAO облегчает приложению миграцию на другую реализацию базы данных. Бизнес-объекты не знают о деталях реализации используемых данных. Следовательно, процесс миграции требует изменений только в уровне DAO. Более того, при использовании стратегии генератора можно предоставить конкретную реализацию генератора для каждой реализации хранилища данных. В этом случае миграция на другую реализацию хранилища означает предоставление приложению новой реализации генератора.
- Уменьшает сложность кода в бизнес-объектах Поскольку объекты DAO управляют всеми сложностями доступа к данным, упрощается код бизнес-компонентов и других клиентов данных, использующих DAO. Весь зависящий от реализации код (например, SQL-команды) содержится в DAO, а не в бизнес-объекте. Это улучшает читаемость кода и производительность разработки.
- Централизует весь доступ к данным в отдельном уровне Поскольку все операции доступа к данным реализованы в объектах DAO, отдельный уровень доступа к данным может рассматриваться как уровень, изолирующий остальную часть приложения от реализации доступа к данным. Такая централизация облегчает поддержку и управление приложением.
- Бесполезна для управляемой контейнером персистенции Поскольку EJB-контейнер управляет компонентами с управляемой контейнером персистенцией (CMP — container-managed persistence), контейнер автоматически обслуживает весь доступ к хранилищу данных. Приложения, использующие компоненты управления данными этого типа, не нуждаются в уровне объектов DAO, поскольку сервер приложений обеспечивает эту функциональность. Однако, объекты DAO остаются полезны в случаях, когда необходимо использовать комбинацию CMP (для компонентов управления данными) и BMP (для сессионных компонентов, сервлетов).
- Добавляет дополнительный уровень Объекты DAO создают дополнительный уровень объектов между клиентом данных и источником данных, который должен быть разработан и реализован для использования преимуществ, предлагаемых данным паттерном. Но за реализуемые при этом преимущества приходится платить дополнительными усилиями при разработке.
- Требуется разработка иерархии классов При использовании стратегии генератора необходимо разработать и реализовать иерархию конкретных генераторов и иерархию конкретных объектов, производимых генераторами. Эти дополнительные усилия необходимо принимать во внимание, если существует достаточно оснований для реализации такой гибкости. Это увеличивает сложность разработки. Однако, вы можете сначала реализовать эту стратегию с паттерном Factory Method, а затем, при необходимости, перейти к паттерну Abstract Factory.
6 Примеры
6.1 Реализация паттерна Data Access Object
Код объекта DAO для персистентного объекта, предоставляющего информацию о клиенте (Customer), представлен в примере 9.4. CloudscapeCustomerDAO создает объект Customer Transfer Object при вызове метода findCustomer() .
Код, использующий DAO, показан в примере 9.6. Диаграмма классов этого примера приведена на рисунке 9.6.
Рисунок 9.6 Реализация паттерна DAO
6.2 Реализация стратегии Factory for Data Access Objects
6.2.1 Использование паттерна Factory Method
Рассмотрим пример, в котором мы применяем данную стратегию для создания генератором многих объектов DAO для одной реализации базы данных (например, Oracle). Генератор производит такие объекты DAO, как CustomerDAO, AccountDAO, OrderDAO и др. Диаграмма классов для этого примера приведена на рисунке 9.7.
Рисунок 9.7 Реализация стратегии Factory for DAO, использующей Factory Method
Код генератора DAO (CloudscapeDAOFactory) приведен в примере 9.2.
6.2.2 Использование паттерна Abstract Factory
Рассмотрим пример, в котором мы применяем данную стратегию для трех различных баз данных. В этом случае может быть использован паттерн Abstract Factory. Диаграмма классов этого примера показана на рисунке 9.8. Код в примере 9.1 показывает фрагмент абстрактного класса DAOFactory. Этот генератор производит такие объекты DAO как CustomerDAO, AccountDAO, OrderDAO и др. Данная стратегия использует реализацию Factory Method в генераторах, созданных при помощи Abstract Factory.
Рисунок 9.8 Реализация стратегии Factory for DAO, использующей Abstract Factory
6.2.3 Пример 9.1 Абстрактный класс DAOFactory
// Абстрактный класс DAO Factory
public abstract class DAOFactory
// Список типов DAO, поддерживаемых генератором
public static final int CLOUDSCAPE = 1 ;
public static final int ORACLE = 2 ;
public static final int SYBASE = 3 ;
.
// Здесь будет метод для каждого DAO, который может быть
// создан. Реализовывать эти методы
// должны конкретные генераторы.
public abstract CustomerDAO getCustomerDAO () ;
public abstract AccountDAO getAccountDAO () ;
public abstract OrderDAO getOrderDAO () ;
.
public static DAOFactory getDAOFactory (
int whichFactory )
switch ( whichFactory ) case CLOUDSCAPE:
return new CloudscapeDAOFactory () ;
case ORACLE :
return new OracleDAOFactory () ;
case SYBASE :
return new SybaseDAOFactory () ;
.
default :
return null ;
>
>
>
Код CloudscapeDAOFactory приведен в примере 9.2. Реализации OracleDAOFactory и SybaseDAOFactory аналогичны, за исключением особенностей каждой реализации, таких как JDBC-драйвер, URL базы данных и различий в синтаксисе SQL, если таковые имеются.
6.2.4 Пример 9.2 Конкретная реализация DAOFactory для Cloudscape
// Конкретная реализация DAOFactory для Cloudscape
import java.sql.*;
public class CloudscapeDAOFactory extends DAOFactory public static final String DRIVER=
«COM.cloudscape.core.RmiJdbcDriver» ;
public static final String DBURL=
«jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB» ;
// метод для создания соединений к Cloudscape
public static Connection createConnection () // Использовать DRIVER и DBURL для создания соединения
// Рекомендовать реализацию/использование пула соединений
>
public CustomerDAO getCustomerDAO () // CloudscapeCustomerDAO реализует CustomerDAO
return new CloudscapeCustomerDAO () ;
>
public AccountDAO getAccountDAO () // CloudscapeAccountDAO реализует AccountDAO
return new CloudscapeAccountDAO () ;
>
public OrderDAO getOrderDAO () // CloudscapeOrderDAO реализует OrderDAO
return new CloudscapeOrderDAO () ;
>
.
>
Интерфейс CustomerDAO, показанный в примере 9.3, определяет DAO-методы для персистентного объекта Customer, которые реализованы всеми конкретными реализациями DAO, такими как, CloudscapeCustomerDAO, OracleCustomerDAO и SybaseCustomerDAO. Аналогично (но здесь не приводится) реализуются интерфейсы AccountDAO и OrderDAO, определяющие DAO-методы соответственно для бизнес-объектов Account и Order.
6.2.5 Пример 9.3 Базовый DAO-интерфейс для Customer
// Интерфейс, который должны поддерживать все CustomerDAO
public interface CustomerDAO public int insertCustomer ( . ) ;
public boolean deleteCustomer ( . ) ;
public Customer findCustomer ( . ) ;
public boolean updateCustomer ( . ) ;
public RowSet selectCustomersRS ( . ) ;
public Collection selectCustomersTO ( . ) ;
.
>
CloudscapeCustomerDAO реализует CustomerDAO, как показаго в примере 9.4. Реализации других объектов DAO, таких как CloudscapeAccountDAO, CloudscapeOrderDAO, OracleCustomerDAO, OracleAccountDAO, и т.д. — аналогичны.
6.2.6 Пример 9.4 Реализация Cloudscape DAO для Customer
// Реализация CloudscapeCustomerDAO
// интерфейса CustomerDAO. Этот класс может содержать весь
// специфичный для Cloudscape код и SQL-команды.
// Клиент, таким образом, защищается от необходимости
// знать эти детали реализации.
public class CloudscapeCustomerDAO implements
CustomerDAO
public CloudscapeCustomerDAO () // инициализация
>
// Следующие методы по необходимости могут использовать
// CloudscapeDAOFactory.createConnection()
// для получения соединения
public int insertCustomer ( . ) // Реализовать здесь операцию добавления клиента.
// Возвратить номер созданного клиента
// или -1 при ошибке
>
public boolean deleteCustomer ( . ) // Реализовать здесь операцию удаления клиента.
// Возвратить true при успешном выполнении, false при ошибке
>
public Customer findCustomer ( . ) // Реализовать здесь операцию поиска клиента, используя
// предоставленные значения аргументов в качестве критерия поиска.
// Возвратить объект Transfer Object при успешном поиске,
// null или ошибку, если клиент не найден.
>
public boolean updateCustomer ( . ) // Реализовать здесь операцию обновления записи,
// используя данные из customerData Transfer Object
// Возвратить true при успешном выполнении, false при ошибке
>
public RowSet selectCustomersRS ( . ) // Реализовать здесь операцию выбора клиентов,
// используя предоставленный критерий.
// Возвратить RowSet.
>
public Collection selectCustomersTO ( . ) // Реализовать здесь операцию выбора клиентов,
// используя предоставленный критерий.
// В качестве альтернативы, реализовать возврат
// коллекции объектов Transfer Object.
>
.
>
Класс Customer Transfer Object показан в примере 9.5. Он используется объектами DAO для передачи и приема данных от клиентов. Использование объектов Transfer Object детально рассматривалось в паттерне Transfer Object.
6.2.7 Пример 9.5 Customer Transfer Object
public class Customer implements java.io.Serializable <
// переменные-члены
int CustomerNumber;
String name;
String streetAddress;
String city;
.
// методы getter и setter.
.
>
В примере 9.6 показано использование генератора DAO и DAO. Если реализация меняется от Cloudscape к другому продукту, необходимо изменить только вызов метода getDAOFactory() в генераторе DAO для получения другого генератора.
6.2.8 Пример 9.6 Использование DAO и DAO-генератора — код клиента
.
// создать требуемый генератор DAO
DAOFactory cloudscapeFactory =
DAOFactory.getDAOFactory ( DAOFactory.DAOCLOUDSCAPE ) ;
// Создать DAO
CustomerDAO custDAO =
cloudscapeFactory.getCustomerDAO () ;
// создать нового клиента
int newCustNo = custDAO.insertCustomer ( . ) ;
// найти объект customer. Получить объект Transfer Object.
Customer cust = custDAO.findCustomer ( . ) ;
// изменить значения в Transfer Object.
cust.setAddress ( . ) ;
cust.setEmail ( . ) ;
// обновить объект customer, используя DAO
custDAO.updateCustomer ( cust ) ;
// удалить объект customer
custDAO.deleteCustomer ( . ) ;
// выбрать всех клиентов одного города
Customer criteria= new Customer () ;
criteria.setCity ( «New York» ) ;
Collection customersList =
custDAO.selectCustomersTO ( criteria ) ;
// возвратить customersList — коллекцию объектов Customer
// Transfer Objects. Проходит по коллекции для
// получения значений.
7 Связанные паттерны
- Transfer Object DAO использует Transfer Objects для передачи данных клиентам и от них.
- Factory Method [GoF] и Abstract Factory [GoF] Стратегия Factory for Data Access Objects использует паттерн Factory Method для реализации конкретных генераторов и их продуктов (объектов DAO). Для дополнительной гибкости, в стратегиях может быть применен паттерн Abstract Factory, как рассматривалось выше.
- Broker [POSA1] Паттерн DAO связан с паттерном Broker, который описывает подходы для разделения клиентов и серверов в распределенных системах. Паттерн DAO применяет этот паттерн более конкретно для разделения уровня ресурсов от клиентов и перемещения его в другой уровень, такой как бизнес-уровень, или уровень представлений.
A может Вас также заинтересует что-нибудь из этого:
- J2EE → Паттерн Session Facade
- J2EE → Composite Entity паттерн
- J2EE → Паттерн Value List Handler
- J2EE → Паттерны: Business Delegate
- J2EE → Паттерн Intercepting Filter
- J2EE → JSTL: Шаблоны для разработки веб-приложений в java. Часть 1
Ответы на вопросы на собеседование Design patterns.
Порождающие шаблоны предназначаются для организации процесса создания объектов и все до единого соответствуют шаблону Creator из GRASP.
К порождающим шаблонам относятся:
- Abstract Factory (Абстрактная Фабрика) — предоставляет интерфейс для создания связанных между собой объектов семейств классов без указания их конкретных реализаций (families of product objects);
- Factory Method (Фабричный метод) — определяет интерфейс для создания объектов из иерархического семейства классов на основе передаваемых данных (subclass of object that is instantiated);
- Builder (Строитель) — создает объект конкретного класса различными способами (how a composite object gets created);
- Singleton (Одиночка) — гарантирует существование только одного или конечного числа экземпляров класса (the sole instance of a class);
- Prototype (Прототип) — применяется при создании сложных объектов. На основе прототипа объекты сохраняются и воссоздаются, например, путем копирования (class of object that is instantiated).
- Назовите шаблоны поведения, и кратко опишите их.
Шаблоны поведения GoF характеризуют способы взаимодействия классов или объектов между собой.
К шаблонам поведения относятся:
- Chain of Responsibility (Цепочка Обязанностей) — организует независимую от объекта-отправителя цепочку не знающих возможностей друг друга объектов-получателей, которые передают запрос друг другу (object that can fulfill a request);
- Command (Команда) — используется для определения по некоторому признаку объекта конкретного класса, которому будет передан запрос для обработки (when and how a request is fulfilled);
- Iterator (Итератор) — позволяет последовательно обойти все элементы коллекции или другого составного объекта, не зная деталей внутреннего представления данных (how an aggregate’s elements are accessed, traversed);
- Mediator (Посредник) — позволяет снизить число связей между классами при большом их количестве, выделяя один класс, знающий все о методах других классов (how and which objects interact with each other);
- Memento (Хранитель) — сохраняет текущее состояние объекта для дальнейшего восстановления (what private information is stored outside an object, and when);
- Observer (Наблюдатель) — позволяет при зависимости между объектами типа «один ко многим» отслеживать изменения объекта (number of objects that depend on another object; how the dependent objects stay up to date);
- State (Состояние) — позволяет объекту изменять свое поведение за счет изменения внутреннего объекта состояния (states of an object);
- Strategy (Стратегия) — задает набор алгоритмов с возможностью выбора одного из классов для выполнения конкретной задачи во время создания объекта (an algorithm);
- Template Method (Шаблонный Метод) — создает родительский класс, использующий несколько методов, реализация которых возложена на производные классы (steps of an algorithm);
- Visitor (Посетитель) — представляет операцию в одном или нескольких связанных классах некоторой структуры, которую вызывает специфичный для каждого такого класса метод в другом классе (operations that can be applied to object(s) without changing their class(es));
- Interpreter (Интерпретатор) — для определенного способа представления информации определяет правила (grammar and interpretation of a language).
- Назовите структурные шаблоны, и кратко опишите их.
Структурные шаблоны GoF отвечают за композицию объектов и классов, и не только за объединение частей приложения, но и за их разделение.
К структурным шаблонам относятся:
- Adapter (Адаптер) — применяется при необходимости использовать классы вместе с несвязанными интерфейсами. Поведение адаптируемого класса при этом изменяется на необходимое (interface to an object);
- Bridge (Мост) — разделяет представление класса и его реализацию, позволяя независимо изменять то и другое (implementation of an object);
- Composite (Компоновщик) — группирует объекты в иерархические древовидные структуры и позволяет работать с единичным объектом так же, как с группой объектов (structure and composition of an object);
- Decorator (Декоратор) — представляет способ изменения поведения объекта без создания подклассов. Позволяет использовать поведение одного объекта в другом (responsibilities of an object without subclassing);
- Facade (Фасад) — создает класс с общим интерфейсом высокого уровня к некоторому числу интерфейсов в подсистеме (interface to a subsystem);
- Flyweight (Легковес) — разделяет свойства класса для оптимальной поддержки большого числа мелких объектов (storage costs of objects);
- Proxy (Заместитель) — подменяет сложный объект более простым и осуществляет контроль доступа к нему (how an object is accessed. its location).
- Какие антишаблоны вы знаете?
- Big ball of mud (Большой Ком Грязи) — термин для системы или просто программы, которая не имеет хоть немного различимой архитектуры. Как правило, включает в себя более одного антишаблона. Этим страдают системы, разработанные людьми без подготовки в области архитектуры ПО.
- Yo-Yo problem (Проблема Йо-Йо) — возникает, когда необходимо разобраться в программе, иерархия наследования и вложенность вызовов методов которой очень длинны и сложны. Программисту вследствие этого необходимо лавировать между множеством различных классов и методов, чтобы контролировать поведение программы. Термин происходит от названия игрушки йо-йо.
- Magic Button — возникает, когда код обработки формы сконцентрирован в одном месте и, естественно, никак не структурирован.
- Magic Number — наличие в коде многократно повторяющихся одинаковых чисел или чисел, объяснение происхождения которых отсутствует.
- Gas Factory (Газовый Завод) — необязательный сложный дизайн для простой задачи.
- Analiys paralisys. В разработке ПО (Паралич анализа) — проявляет себя через чрезвычайно длинные фазы планирования проекта, сбора необходимых для этого артефактов, программного моделирования и дизайна, которые не имеют особого смысла для достижения итоговой цели.
- Interface Bloat (Распухший Интерфейс) — термин, используемый для описания интерфейсов, которые пытаются вместить в себя все возможные операции над данными.
- Accidental complexity (Случайная сложность) — проблема в программировании, которой легко можно было избежать. Возникает вследствие неправильного понимания проблемы или неэффективного планирования.
OOAD, Object Oriented Analysis and Design (Объектно-ориентированный анализ и проектирование) — дисциплина, описывающая способы (варианты) задания (определения) объектов и их взаимодействие для решения проблемы, которая определена и описана в ходе объектно-ориентированного анализа.
Основная идея объектно-ориентированного анализа и проектирования (object-oriented analysis and design) состоит в рассмотрении предметной области и логического решения задачи с точки зрения объектов (понятий и сущностей). В процессе объектно-ориентированного анализа основное внимание уделяется определению и описанию объектов (или понятий) в терминах предметной области. В процессе объектно-ориентированного проектирования определяются логические программные объекты, которые будут реализованы средствами объектно-ориентированного языка программирования. Эти программные объекты включают в себя атрибуты и методы. И, наконец, в процессе конструирования (construction) или объектно-ориентированного программирования (object-oriented programming) обеспечивается реализация разработанных компонентов и классов.
OOD, Object Oriented Design (Объектно-ориентированное проектирование) — это методология проектирования, соединяющая в себе процесс объектной декомпозиции и приемы представления логической и физической, а также статической и динамической моделей проектируемой системы.
OOA, Object Oriented Analysis (Объектно-ориентированный анализ) — это методология, при которой требования к системе воспринимаются с точки зрения классов и объектов, выявленных в предметной области, это методология проектирования, соединяющая в себе процесс объектной декомпозиции и приемы представления логической и физической, а также статической и динамической моделей проектируемой системы.
- Что такое DRY principles?
DRY, Don’t repeat yourself (не повторяй себя) — этот принцип настолько важен, что не требует повторения! Это принцип разработки программного обеспечения, нацеленный на снижение повторения информации различного рода, особенно в системах со множеством слоёв абстрагирования, простими словами НЕ пишите повторяющегося кода, используйте принцип абстракции, обобщая простые вещи в одном месте.
KISS, Keep it short and simple или Keep it simple, stupid (делайте вещи проще) — это принцип проектирования и программирования, запрещающий использование более сложных средств, чем необходимо. Принцип декларирует простоту системы в качестве основной цели и/или ценности.
YAGNI, You ain’t gonna need it (Вам это не понадобится) — процесс и принцип проектирования ПО, при котором в качестве основной цели и/или ценности декларируется отказ от избыточной функциональности. Суть в том, чтобы реализовать только поставленные задачи и отказаться от избыточного функционала.
- Что такое Yoda conditions?
Yoda conditions (Условия Йоды в жаргоне программистов) — «безопасный» стиль записи выражений сравнения при программировании на языках с Си-синтаксисом, заключающийся в написании константного члена выражения (константы или вызова функции) слева от оператора сравнения (то есть 5 == a вместо привычного а == 5).
Такой стиль призван предотвратить свойственную данным языкам ошибку — использование оператора присваивания «=» вместо сравнения «= font-family: «arial» , «helvetica» , sans-serif;»>
- Что такое CRC cards?
CRC cards, Class-responsibility-collaboration card (Класс-Ответственность-Кооперация) — метод мозгового штурма, предназначенный для проектирования объектно-ориентированного программного обеспечения. Как правило, CRC-карты используются в тех случаях, когда сначала в процессе проектирования ПО определяются классы и способы их взаимодействий.
CRC-карты акцентируют внимание дизайнера на сущности класса и скрывают от него детали, рассмотрение которых на данном этапе будет контрпродуктивным. CRC-карты также заставляют дизайнера воздержаться от назначения классу слишком многих обязанностей.
SOLID, (single responsibility, open-closed, Liskov substitution, interface segregation и dependency inversion) — акроним для первых пяти принципов, которые означали пять основных принципов объектно-ориентированного программирования и проектирования. Эти принципы, когда применяются вместе, предназначены для повышения вероятности того, что программист создаст систему, которую будет легко поддерживать и расширять в течение долгого времени. Принципы SOLID — это руководства, которые могут применяться во время работы над программным обеспечением для удаления «кода с запашком» предписывая программисту выполнять рефакторинг исходного кода, пока тот не станет разборчиво написанным и расширяемым. Это часть общей стратегии гибкой и адаптивной разработки.
- Что такое Single responsibility principle?
Single responsibility principle — принцип единственной обязанности (на каждый класс должна быть возложена одна-единственная обязанность). Если один класс java реализует 2 набора функций, их сцепление создает ситуацию, при которой изменение одного нарушит имеющееся сочетание.
- Что такое Open/closed principle?
Open/closed principle — принцип объектно-ориентированного программирования, устанавливающий следующее положение: «программные сущности (классы, модули, функции и т. п.) должны быть открыты для расширения, но закрыты для изменения»; это означает, что такие сущности могут позволять менять свое поведение без изменения их исходного кода.
- Что такое Liskov substitution principle?
Liskov substitution principle — принцип подстановки Барбары Лисков (функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом. Подклассы не могут замещать поведения базовых классов. Подтипы должны дополнять базовые типы).
- Что такое Interface segregation principle?
Interface segregation principle — принцип разделения интерфейса (много специализированных интерфейсов лучше, чем один универсальный). Иными словами большие, объемные интерфейсы надо разбивать на мелкие таким образом, чтобы клиенты маленьких интерфейсов знали только о тех методах которые необходимы им в работе. И чтобы при изменении метода интерфейса не должны меняться клиенты, которые этот метод не используют.
- Что такое Dependency inversion principle?
Dependency inversion principle — принцип инверсии зависимостей (зависимости внутри системы строятся на основе абстракций. Модули верхнего уровня не зависят от модулей нижнего уровня. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций).
GRASP, General Responsibility Assignment Software Patterns (общие шаблоны распределения обязанностей) — шаблоны проектирования, используемые для решения общих задач по назначению обязанностей классам и объектам. Известно девять GRAPS шаблонов.
- Кратко опишите шаблоны GRAPS.
- Information Expert (Информационные эксперт) — информационный эксперт описывает основополагающие принципы назначения обязанностей классам и объектам. Согласно описанию, информационным экспертом (объектом наделенным некоторыми обязанностями) является объект, обладающий максимумом информацией, необходимой для выполнения назначенных обязанностей.
- Creator (Создатель) — суть ответственности такого объекта в том, что он создает другие объекты. Сразу напрашивается аналогия с фабриками. Так оно и есть. Фабрики тоже имеют именно ответственность — Создатель.
- Controller (Контроллер) — отвечает за обработку входных системных событий, делегируя обязанности по их обработке компетентным классам. В общем случае, контроллер реализует один или несколько вариантов использования. Использование контроллеров позволяет отделить логику от представления, тем самым повышая возможность повторного использования кода.
- Low Coupling (Слабая связанность) — если объекты в приложении сильно связаны, то любой их изменение приводит к изменениям во всех связанных объектах. А это неудобно и порождает баги. Вот по-этому везде пишут, что необходимо, чтобы код был слабо связан и зависел только от абстракций.
- High Cohesion (Высокая сцепленность) — этот принцип тесно соотносится с слабой связанностью, и они идут в паре, когда одно всегда приводит к другому, это как мера того, что мы не нарушаем single resposibility principle. Вернее сказать, высокая сцепленность получается в результате соблюдения такого принципа из SOLID, как single resposibility principle (SRP).
- Pure Fabrication (Чистая выдумка или чистое синтезирование) — это класс, не отражающий никакого реального объекта предметной области, но специально придуманный для усиления связности, ослабления связанности или увеличения степени повторного использования. Pure Fabrication отражает концепцию сервисов в модели Программирование от предметной области.
- Indirection (Посредник) — шаблон перенаправление реализует низкую связность между классами, путем назначения обязанностей по их взаимодействию дополнительному объекту — посреднику.
- Protected Variations (Сокрытие реализации или защищенные изменения) — защищает элементы от изменения других элементов (объектов или подсистем) с помощью вынесения взаимодействия в фиксированный интерфейс. Всё взвимодействие между элементами должно происходить через него. Поведение может варьироваться лишь с помощью создания другой реализации интерфейса.
- Polymorphism (Полиморфизм) — позволяет обрабатывать альтернативные варианты поведения на основе типа и заменять подключаемые компоненты системы. Обязанности распределяются для различных вариантов поведения с помощью полиморфных операций для этого класса. Все альтернативные реализации приводятся к общему интерфейсу.
Книга «Spring. Все паттерны проектирования»
Привет, Хаброжители! Мы издали книгу в которой дается обзор фреймворка Spring 5 и паттернов проектирования для него. Объясняется принцип внедрения зависимостей (dependency injection), играющий ключевую роль при создании слабосвязанного кода во фреймворке Spring. Затем рассматриваются классические паттерны «Банды четырех» при проектировании приложений на Spring. В следующих частях книги автор рассматривает паттерны аспектно-ориентированного программирования (AOP), шаблоны JDBC, позволяющие абстрагировать доступ к базе данных. В заключительных главах книги автор исследует работу с MVC, реактивные шаблоны проектирования и паттерны проектирования, применяемые при конкурентном и параллельном программировании в Spring.
Предлагаем ознакомиться с отрывком «Паттерн «Объект доступа к данным»»
«Объект доступа к данным» (Data Access Object, DAO) — чрезвычайно популярный паттерн проектирования для уровня сохранения в приложениях J2EE. Он отделяет уровень бизнес-логики от уровня сохранения. Паттерн DAO основан на объектно-ориентированных принципах инкапсуляции и абстракции. Контекст использования паттерна DAO — доступ к данным и их сохранение в зависимости от конкретной реализации и типа хранилища, например объектно-ориентированной базы данных, неструктурированных файлов, реляционных баз данных и т. д. На основе паттерна DAO можно создать интерфейс DAO и реализовать его, чтобы абстрагировать и инкапсулировать все обращения к источнику данных. Подобная реализация DAO управляет такими ресурсами базы данных, как соединения с источником данных.
Интерфейсы DAO очень легко адаптируются ко всем нижележащим механизмам источников данных, их не нужно заменять при изменениях в технологиях сохранения на более низких уровнях. Этот паттерн позволяет внедрять различные технологии доступа к данным, никак не затрагивая бизнес-логику корпоративного приложения. Рассмотрим рис. 8.1, чтобы лучше понять принципы паттерна DAO.
Как можно видеть на схеме, в паттерне участвуют следующие объекты.
BusinessObject — объект, работающий на бизнес-уровне, — клиент для уровня доступа к данным. Ему нужны данные, чтобы моделировать бизнес-процессы, а также подготавливать Java-объекты для вспомогательных функций или контроллеров приложения.
DataAccessObject — основной объект паттерна DAO. Скрывает от BusinessObject всю низкоуровневую реализацию работы нижележащей базы данных.
DataSource — тоже объект, содержащий всю низкоуровневую информацию о том, что именно представляет собой нижележащая база данных: RDBMS, неструктурированные файлы или XML.
TransferObject — объект, используемый как носитель информации. Применяется объектом DataAccessObject для возврата данных объекту BusinessObject.
Рассмотрим следующий пример паттерна DAO, в котором AccountDao представляет собой интерфейс объекта DataAccessObject, а AccountDaoImpl — класс, реализующий интерфейс AccountDao:
public interface AccountDao < Integer totalAccountsByBranch(String branchName); >public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao < @Override public Integer totalAccountsByBranch(String branchName) < String sql = "SELECT count(*) FROM Account WHERE branchName = "+branchName; return this.getJdbcTemplate().queryForObject(sql, Integer.class); >>
Создание объектов DAO в Spring с помощью паттерна проектирования «Фабрика»
Как вы знаете, во фреймворке Spring задействуется множество паттернов проектирования. Паттерн «Фабрика» представляет собой порождающий паттерн проектирования и используется для создания объекта без раскрытия клиенту нижележащей логики, а также назначения вызывающей стороне нового объекта с помощью общего интерфейса или абстрактного класса. Благодаря паттернам проектирования «Фабричный метод» и «Абстрактная фабрика» можно достичь очень высокой гибкости паттерна DAO.
Выясним, где в нашем примере мы реализуем стратегию, в которой фабрика производит объекты DAO для реализации общей базы данных (рис. 8.2).
Вы можете увидеть на предыдущей схеме, что AccountDaoFactory производит объект AccountDao, то есть является для него фабрикой. Нижележащую базу данных можно заменить в любой момент, при этом бизнес-код менять не нужно — фабрика берет эту работу на себя. Spring поддерживает хранение всех DAO в фабрике компонентов, а также в фабрике DAO.
Паттерн «Отображение данных»
Фреймворк ORM обеспечивает отображение между объектами и реляционными базами данных, ведь объекты и таблицы реляционных баз данных по-разному хранят данные приложения. Кроме того, в объектах и таблицах есть различные механизмы структурирования данных. При использовании в приложении Spring любого ORM-решения, например Hibernate, JPA или JDO, нет нужды волноваться о механизме отображения между объектами и реляционными базами данных.
Рассмотрим рис. 8.3, чтобы лучше разобраться с паттерном «Отображение данных» (Data Mapper).
На схеме происходит отображение объекта Account в реляционную базу данных посредством интерфейса AccountMapper. AccountMapper играет в приложении роль посредника между Java-объектом и нижележащей базой данных. Рассмотрим еще один паттерн, используемый на уровне доступа к данным.
Паттерн «Модель предметной области»
Модель предметной области — объект, у которого есть и данные, и поведение, где поведение определяет бизнес-логику корпоративного приложения, а данные представляют собой информацию о результатах бизнеса. Модель предметной области объединяет данные и технологический процесс. В корпоративном приложении модель данных располагается ниже бизнес-уровня и определяет бизнес-логику, возвращая результаты бизнес-поведения. Рассмотрим следующую схему для большей ясности (рис. 8.4).
Как можно видеть на схеме, в приложении заданы две модели предметной области в соответствии с бизнес-требованиями. Бизнес-алгоритм перевода денег с одного счета на другой описан в классе TransferService. Классы TransferService и AccountService относятся к паттерну «Модель предметной области» в корпоративном приложении.
Прокси для паттерна «Отложенная загрузка»
«Отложенная загрузка» — паттерн проектирования, используемый некоторыми из ORM-решений, например Hibernate, в корпоративных приложениях, чтобы отложить инициализацию объекта до момента обращения к нему другого объекта, то есть момента, когда он понадобится. Цель этого паттерна проектирования состоит в оптимизации памяти в приложении. Паттерн проектирования «Отложенная загрузка» в Hibernate реализуется с помощью виртуального объекта-прокси. При демонстрации отложенной загрузки мы используем прокси, но он не относится к паттерну «Заместитель».
Паттерн «Шаблонный метод» для поддержки Hibernate в Spring
Фреймворк Spring предоставляет вспомогательный класс для доступа к данным на уровне DAO, основанный на паттерне проектирования «Шаблонный метод» GoF. Класс HibernateTemplate фреймворка Spring поддерживает такие операции баз данных, как save, create, delete и update. Этот класс гарантирует, что для каждой транзакции используется только один сеанс Hibernate.
Интеграция Hibernate со Spring
Hibernate — ORM-фреймворк сохранения с открытым исходным кодом, который не только обеспечивает отображение простых объектных взаимосвязей между Java-объектами и таблицами базы данных, но и предлагает множество продвинутых возможностей для повышения производительности приложения, а также помогает улучшить использование ресурсов, например с помощью кэширования, отложенной загрузки, немедленного извлечения данных и распределенного кэширования.
Spring обеспечивает полную поддержку интеграции с фреймворком Hibernate, у него имеется несколько встроенных библиотек, позволяющих задействовать Hibernate на все 100 %. Для задания настроек Hibernate в приложении можно воспользоваться паттерном внедрения зависимостей и контейнером IoC фреймворка Spring.
В следующем разделе мы выясним, как правильно настроить Hibernate в контейнере IoC фреймворка Spring.
Задание настроек объекта SessionFactory фреймворка Hibernate в контейнере Spring
Оптимальный подход к настройке Hibernate и других технологий сохранения в любом корпоративном приложении состоит в разделении бизнес-объектов с жестко «зашитыми» справочниками ресурсов, такими как DataSource в JDBC или SessionFactory в Hibernate. Эти ресурсы можно описать в виде компонентов в контейнере Spring. Но для доступа к ним бизнес-объектам необходимы ссылки на них. Рассмотрим следующий класс DAO, использующий объект SessionFactory для получения данных для приложения:
public class AccountDaoImpl implements AccountDao < private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) < this.sessionFactory = sessionFactory; >// . >
Как можно видеть, класс DAO, AccountDaoImpl, следует паттерну внедрения зависимостей. Для доступа к данным в него внедряется объект SessionFactory фреймворка Hibernate, и он прекрасно чувствует себя в контейнере IoC Spring. Объект SessionFactory фреймворка Hibernate представляет собой объект-одиночку, он генерирует основной объект интерфейса Hibernate org.hibernate.Session. Объект SessionFactory управляет объектом Session, а также отвечает за его открытие и закрытие. Интерфейс Session содержит реальную функциональность доступа к данным — сохранения (save), обновления (update), удаления (delete) и загрузки (load) объектов из базы данных. В приложении объект класса AccountDaoImpl или любой другой репозиторий выполняет с помощью этого объекта Session все необходимые операции хранения данных.
Фреймворк Spring предоставляет встроенные модули Hibernate, так что вы можете использовать в своих приложениях компоненты SessionFactory Hibernate.
Компонент org.springframework.orm.hibernate5.LocalSessionFactoryBean представляет собой реализацию интерфейса FactoryBean фреймворка Spring. LocalSessionFactoryBean основан на паттерне «Абстрактная фабрика», он генерирует в приложении объект SessionFactory. Этот объект можно сконфигурировать в виде компонента в контексте Spring приложения следующим образом:
@Bean public LocalSessionFactoryBean sessionFactory(DataSource dataSource) < LocalSessionFactoryBean sfb = new LocalSessionFactoryBean(); sfb.setDataSource(dataSource); sfb.setPackagesToScan(new String[] < "com.packt.patterninspring.chapter8.bankapp.model" >); Properties props = new Properties(); props.setProperty("dialect", "org.hibernate.dialect.H2Dialect"); sfb.setHibernateProperties(props); return sfb; >
В этом коде мы сконфигурировали объект SessionFactory в виде компонента с помощью класса LocalSessionFactoryBean фреймворка Spring. Метод этого компонента принимает на входе объект типа DataSource в качестве аргумента, который определяет место и способ соединения с базой данных. Мы также указали, какой пакет просматривать, задав значение «com.packt.patterninspring.chapter8.bankapp.model» для свойства setPackagesToScan компонента LocalSessionFactoryBean, и задали свойство dialect компонента SessionFactory с помощью метода setHibernateProperties для указания того, с каким типом базы данных мы имеем дело в приложении.
Теперь, после настройки компонента SessionFactory Hibernate, в контексте приложения Spring посмотрим, как можно реализовать объекты доступа к данным для уровня сохранения нашего приложения.
Об авторе
Динеш Раджпут — главный редактор сайта Dineshonjava, технического блога, посвященного технологиям Java и Spring. На сайте размещены статьи на тему Java-технологий. Динеш — блогер, автор книг, c 2008 года энтузиаст Spring, сертифицированный специалист компании Pivotal (Pivotal Certified Spring Professional). Обладает более чем десятилетним опытом проектирования и разработки с использованием Java и Spring. Специализируется на работе с последней версией Spring Framework, Spring Boot, Spring Security, на создании REST API, архитектуре микросервисов, реактивном программировании, аспектно-ориентированном программировании с применением Spring, паттернах проектирования, Struts, Hibernate, веб-сервисах, Spring Batch, Cassandra, MongoDB, архитектуре веб-приложений.
В настоящее время Динеш работает менеджером по технологиям в одной из компаний, лидирующих в области создания программного обеспечения (ПО). Был разработчиком и руководителем команды в Bennett, Coleman & Co. Ltd, а до этого — ведущим разработчиком в Paytm. Динеш с восторгом относится к новейшим технологиям Java и любит писать о них в технических блогах. Является активным участником Java- и Spring-сообществ на различных форумах. Динеш — один из лучших специалистов по Java и Spring.
О рецензенте
Раджив Кумар Мохан обладает большим опытом разработки ПО и корпоративного обучения. На протяжении 18 лет он работал в таких крупнейших IT-компаниях, как IBM, Pentasoft, Sapient и Deft Infosystems. Начал карьеру как программист, руководил многими проектами.
Является экспертом в предметной области Java, J2EE и родственных фреймворках, Android, UI-технологиях. Сертифицирован компанией Sun в качестве Java-программиста (SCJP, Sun Certified Java Programmer) и веб-разработчика на Java (Sun Certified Web Component Developer, SCWCD). Раджив имеет четыре высших образования: в области информатики (Computer Science), прикладной информатики (Computer Applications), органической химии и делового администрирования (MBA). Является консультантом по подбору персонала и экспертом по обучению в HCL, Amdocs, Steria, TCS, Wipro, Oracle University, IBM, CSC, Genpact, Sapient Infosys и Capgemini.
Раджив — основатель фирмы SNS Infotech, расположенной в городе Большая Нойда. Кроме того, он работал в Национальном институте технологий моды (National Institute Of Fashion Technology, NIFT).
Для Хаброжителей скидка 20% по купону — Spring