Что такое гибернация? Основы реализации Hibernate Core

Опубликовано: 2013-04-17

Пример спящего режима Java

Hibernate — это проект среды Java с открытым исходным кодом. Выполняйте мощные объектно-реляционные сопоставления и запросы к базам данных с помощью HQL и SQL.

В целом, широко используемые библиотеки хорошо спроектированы и реализованы, и очень интересно поучиться у них некоторым передовым методам кодирования.

Давайте заглянем внутрь основной библиотеки hibernate и откроем для себя некоторые из ее ключей дизайна.

В этом посте JArchitect анализирует Hibernate Core, чтобы углубиться в его дизайн и реализацию.

Пакет по функциям

Package-by-feature использует пакеты для отражения набора функций. Он помещает все элементы, относящиеся к одной функции (и только этой функции), в один каталог/пакет. В результате получаются пакеты с высокой связностью и высокой модульностью, а также с минимальной связью между пакетами. Элементы, которые тесно связаны друг с другом, размещаются рядом друг с другом.

Ядро Hibernate содержит множество пакетов, каждый из которых связан с определенной функцией hql, sql и другими.

Пакеты ядра Hibernate - Crunchify.com

Связь

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

Вот три основных преимущества использования интерфейсов:

  • Интерфейс предоставляет способ определения контракта, способствующего повторному использованию. Если объект реализует интерфейс, то этот объект должен соответствовать стандарту. Объект, который использует другой объект, называется потребителем. Интерфейс — это контракт между объектом и его потребителем.
  • Интерфейс также обеспечивает уровень абстракции, облегчающий понимание программ. Интерфейсы позволяют разработчикам начать говорить об общем способе поведения кода, не вдаваясь в множество подробных деталей.
  • Интерфейс обеспечивает низкую связь между компонентами, что позволяет легко защитить потребителя интерфейса от любых изменений реализации в классах, реализующих интерфейсы.

Давайте найдем все интерфейсы, определенные Hibernate Core, для этого мы используем CQLinq для запроса базы кода.

jboss11 - Crunchify.com

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

Класс A реализует интерфейс IA, который содержит метод calculate(), потребительский класс C реализован следующим образом.

Класс C вместо ссылки на интерфейс IA ссылается на класс A, в этом случае мы теряем преимущество низкой связи, и эта реализация имеет два основных недостатка:

  • Если мы решим использовать другую реализацию IA, мы должны изменить код класса C.
  • Если некоторые методы добавляются к A, не существующим в IA, и C их использует, мы также теряем контрактное преимущество использования интерфейсов.

C# представил языку возможность явной реализации интерфейса, чтобы гарантировать, что метод из IA никогда не будет вызываться из ссылки на конкретные классы, а только из ссылки на интерфейс. Этот метод очень полезен для защиты разработчиков от потери преимуществ использования интерфейсов.

С JArchitect мы можем проверять такие ошибки с помощью CQLinq , идея состоит в том, чтобы искать все методы из конкретных классов, используемые непосредственно другими методами.

Детали hibernate2 - Crunchify.com

Например, с этой проблемой связан метод getEntityPersister из SessionFactoryImpl, который реализует интерфейс SessionFactoryImplementor.

Давайте найдем методы, вызывающие непосредственно SessionFactoryImpl.getEntityPersister.

Руководство по гибернации - Crunchify.com

Такие методы, как SessionImpl.instantiate, вызывают getEntityPersister напрямую, а не через интерфейс, что нарушает преимущества использования интерфейсов. К счастью, ядро ​​hibernate не содержит многих методов, имеющих эту проблему.

Соединение с внешними ясами

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

Другая библиотека может:

  • Иметь больше возможностей
  • Более могущественный
  • Более безопасный

Давайте возьмем пример antlr lib , которая использовалась для анализа запросов hql, и представим, что был создан еще один парсер, более мощный, чем antlr. Можем ли мы легко заменить antlr новым парсером?

Чтобы ответить на этот вопрос, давайте посмотрим, какие методы из hibernate используют его напрямую:

Детали режима гибернации — Crunchify

И какие из них использовали его косвенно:

Hibernate Funda - Учебники по Java - Crunchify

Многие методы используют antlr напрямую, что делает ядро ​​hibernate тесно связанным с ним, а замена antlr другим — непростая задача. этот факт не означает, что у нас есть проблема в дизайне спящего режима, но мы должны быть осторожны при использовании сторонней библиотеки и хорошо проверять, должна ли сторонняя библиотека быть слабо связана с приложением или нет.

Сплоченность

Принцип единой ответственности гласит, что у класса должна быть одна и только одна причина для изменения. Такой класс называется сплоченным. Высокое значение LCOM обычно указывает на плохо сплоченный класс. Существует несколько показателей LCOM. LCOM принимает значения в диапазоне [0-1]. LCOMHS (HS означает Henderson-Sellers) принимает значения в диапазоне [0-2]. Обратите внимание, что метрика LCOMHS часто считается более эффективной для обнаружения несвязных типов.

Значение LCOMHS выше 1 должно вызывать тревогу.

В целом классы, более связанные с целостностью, — это классы, имеющие много методов и полей.

Давайте искать типы, имеющие много методов и полей.

спящий режим6 - Crunchify

Этот запрос затрагивает лишь несколько типов, и для всех них LCOMHS меньше 1.

Использование аннотаций

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

Давайте найдем все аннотации, определенные ядром hibernate.

hibernate7 - Crunchify.com

Определено множество аннотаций, что упрощает использование спящего режима разработчиками и позволяет избежать головной боли файлов конфигурации.

Заключение

Hibernate Core — хороший пример проектов с открытым исходным кодом, из которых можно извлечь уроки, не стесняйтесь заглянуть внутрь него.