Привет, Хабр! У нас совсем недавно вышла книга "Изучаем Java EE. Современное программирование для больших предприятий" от немецкого Java-чемпиона Себастьяна Дашнера.
![](https://habrastorage.org/r/w780q1/webt/lb/zz/5c/lbzz5cdzefa6q-f5fv5sruxhzck.jpeg)
Господин Дашнер активно пишет и выступает на темы, связанные с современной Java EE, поэтому в своем блоге не обошел вниманием и общие принципы проектирования для платформы Jakarta EE, ныне разрабатываемой Eclipse. Перевод именно этой статьи (июньской) мы сегодня предлагаем вашему вниманию.
Платформа Jakarta EE постепенно вступает в свои права, а вместе с ней появляются новые спецификации для enterprise-разработки. Чтобы согласовать различные стандарты и технологии, которые вот-вот сформируются, все сообщество Java EE только выиграет, если удастся выработать общие принципы проектирования для спецификаций Jakarta EE.
Я считаю, что технология Java EE оказалась столь успешной благодаря всего нескольким принципам. Ниже я изложу мою точку зрения на то, какие принципы проектирования, сложившиеся в Java EE, кажутся мне наиболее важными, какие достойны дальнейшей проработки и потенциально могут послужить рекомендациями для проектирования в Jakarta EE.
Я решил написать эту статью, вдохновившись предложениями Дмитрия Корнилова о том, в каком направлении должно пойти техническое развитие Jakarta EE.
Первым делом – бизнес-логика
Модель программирования, принятая в Java EE, позволяет разработчику сосредоточиться именно на том, на чем требуется – то есть, на бизнес-логике. Больше не требуется наследовать классы API; разработчик может излагать логику своей предметной области на обычном языке Java и преимущественно декларативно (при помощи аннотаций) управлять поведением сервера приложений. Таким образом, фреймворк гладко интегрируется в ваш код и, в сущности, его столь же легко оттуда убрать. При проектировании рассчитывайте не на переиспользование, а на легкое удаление.
Однако, реализации должны по максимуму избавлять разработчика от наиболее тяжелого труда – то есть, позволить ему отвлечься от технических требований, не связанных с бизнес-логикой. Примеры – многопоточность, транзакции, инверсия управления или обработка HTTP-запросов. На стороне приложения занудство – благо :)
Мне кажется важным, что фреймворк не только не мешает реализации бизнес-логики, но и стимулирует программистов быстрее выводить в продакшен разрабатываемые возможности. Незачем полировать фреймворк до блеска – лучше довести до идеала код бизнес-логики. Сравните современную Java EE или Spring с дедовскими версиями J2EE – думаю, сразу поймете, о чем я.
Jakarta EE должна развиваться в том же русле и, соответственно, сосредоточиться на спецификациях, которые позволят разработчикам максимально быстро реализовывать бизнес-логику.
Соглашения по конфигурации
В Java EE сведена к минимуму конфигурация, необходимая для определения типичного корпоративного приложения. В большинстве практических ситуаций соглашения работают прямо из коробки, никакой конфигурации соблюдать не требуется. Так, больше не нужно никаких XML-файлов, чтобы сконфигурировать простое приложение для Java EE. Другой пример – в JAX-RS предоставляются действующие по умолчанию коды HTTP-откликов, соответствующие возвращаемым значениям методов JAX-RS.
Java EE действительно обладает достаточной гибкостью, позволяющей модифицировать поведение и реализовать более сложные сценарии; однако, соглашения по этому поводу нет.
Jakarta EE должна и далее превращать простое в легкое, а сложное – в возможное.
Интероперабельность спецификаций
Jakarta EE должна продолжать и расширять интероперабельность спецификаций. В Java EE соблюдаются существующие спецификации и та присутствующая в них функциональность, которая уже стала частью стандарта.
Разработчики могут рассчитывать на то, что разрозненные спецификации будут хорошо взаимодействовать друг с другом, и никакой конфигурации при этом не потребуется. Стандарты требовали: если среда времени выполнения поддерживает как спецификацию A, так и спецификацию B, то A + B должны взаимодействовать друг с другом. Примеры: валидация компонентов, JAXB или JSON-B могут применяться в классах ресурсов JAX-RS, и никакой дальнейшей конфигурации не требуется.
Внедрение зависимостей и CDI
Конечно, нежелательно, чтобы в Jakarta EE заново изобретались те вещи, которые уже существуют – например, внедрение зависимостей, относящееся к CDI. Желательно, чтобы спецификации использовали и акцентировали сильные стороны JSR 330 или, если потребуется, CDI.
Свежий пример — использование
Другая конкретная мера такова: в спецификациях должны предоставляться поставщики CDI, а при необходимости – квалификаторы typesafe для типов, которые потребуется создавать. Так, на настоящий момент экземпляр клиента JAX-RS можно получить только программно, через API
Декларативные подходы
При всем этом API Java EE серьезно полагается на декларативный подход, при этом используется инверсия управления. Таким образом, разработчики не вызывают функционал напрямую; за вызов функционала отвечает контейнер, при этом мы опираемся на определения кода. Примеры (из наиболее современных спецификаций) — JAX-RS, JSON-B или CDI.
Jakarta EE не только предоставляет более исчерпывающие программные API, но и должна в дальнейшем способствовать применению декларативных определений и инверсии управления.
Стратегии развертывания
Характернейшая особенность (а на мой взгляд – и большое преимущество) Java EE заключается в том, что предлагаемая здесь модель развертывания, в которой проблемы бизнес-логики отмежевываются от реализации. Разработчик программирует исключительно под API, который не входит в состав артефакта развертывания и реализуется контейнером приложения.
Такие компактные артефакты развертывания упрощают и ускоряют доставку программы, в том числе, сборку, публикацию и развертывание как таковое. Также они совместимы с уровнями контейнерной файловой системы, используемой, например, в Docker. В процессе сборки необходимо всего лишь пересобрать или повторно передать изменившиеся элементы.
В идеале артефакты развертывания должны содержать только бизнес-логику и ничего кроме; реализации времени исполнения и потенциально добавляемые сторонние библиотеки доставляются на более низком уровне, например, в серверных библиотеках приложения, добавленных на предыдущем этапе сборки контейнера.
В Jakarta EE развернутые артефакты также должны считаться сущностями первого класса. Возможно, там появится возможность еще сильнее ужать среду времени исполнения на основе спецификации, требуемой приложением. Однако, в Jakarta EE предполагается уделять максимум внимания бизнес-логике и продуктивности разработчика, а доводка времени исполнения уже вторична.
Тестируемость
Применяя вышеперечисленные принципы, особенно отдавая предпочтение декларативному программированию и внедрению зависимостей, мы совершенствуем тестируемость бизнес-кода. Таким образом, разработчики могут напрямую инстанцировать объекты в тестовых сценариях, поскольку теперь не требуется наследовать классы API или вызывать неудобный функционал, который ранее потребовалось бы сымитировать.
Однако, в Jakarta EE требуется серьезно доработать стандартизацию интеграционного тестирования на уровне кода, так, чтобы оно не зависело от производителя. Ранее именно с этим приходилось иметь дело при работе с Arquillian. В реальных проектах был бы полезен такой стандарт, который позволяет объявлять только сценарии тестового развертывания и вызывать функционал для одного или нескольких компонентов. Ранее я уже писал, что не считаю чрезмерно важным интеграционное тестирование на уровне кода, например, при выполнении приложения во встроенных контейнерах. Однако, если стандартизировать интеграционные тесты на уровне кода, это явно даст положительный эффект.
Заключение
Думаю, неслучайно API Java EE так широко применяются в реальных проектах: эти API хорошо продуманы и спроектированы в соответствии с четкими принципами, благодаря которым удалось унифицировать даже не единственную спецификацию, а целую платформу. Они позволяют пользоваться сразу несколькими спецификациями, выдержанными в едином духе. Здесь удалось избавиться от искусственных препятствий, только усложняющих работу программиста – поэтому, полагаю, вся enterprise-разработка стала гораздо приятнее.
![](https://habrastorage.org/webt/lb/zz/5c/lbzz5cdzefa6q-f5fv5sruxhzck.jpeg)
Господин Дашнер активно пишет и выступает на темы, связанные с современной Java EE, поэтому в своем блоге не обошел вниманием и общие принципы проектирования для платформы Jakarta EE, ныне разрабатываемой Eclipse. Перевод именно этой статьи (июньской) мы сегодня предлагаем вашему вниманию.
Платформа Jakarta EE постепенно вступает в свои права, а вместе с ней появляются новые спецификации для enterprise-разработки. Чтобы согласовать различные стандарты и технологии, которые вот-вот сформируются, все сообщество Java EE только выиграет, если удастся выработать общие принципы проектирования для спецификаций Jakarta EE.
Я считаю, что технология Java EE оказалась столь успешной благодаря всего нескольким принципам. Ниже я изложу мою точку зрения на то, какие принципы проектирования, сложившиеся в Java EE, кажутся мне наиболее важными, какие достойны дальнейшей проработки и потенциально могут послужить рекомендациями для проектирования в Jakarta EE.
Я решил написать эту статью, вдохновившись предложениями Дмитрия Корнилова о том, в каком направлении должно пойти техническое развитие Jakarta EE.
Первым делом – бизнес-логика
Модель программирования, принятая в Java EE, позволяет разработчику сосредоточиться именно на том, на чем требуется – то есть, на бизнес-логике. Больше не требуется наследовать классы API; разработчик может излагать логику своей предметной области на обычном языке Java и преимущественно декларативно (при помощи аннотаций) управлять поведением сервера приложений. Таким образом, фреймворк гладко интегрируется в ваш код и, в сущности, его столь же легко оттуда убрать. При проектировании рассчитывайте не на переиспользование, а на легкое удаление.
Однако, реализации должны по максимуму избавлять разработчика от наиболее тяжелого труда – то есть, позволить ему отвлечься от технических требований, не связанных с бизнес-логикой. Примеры – многопоточность, транзакции, инверсия управления или обработка HTTP-запросов. На стороне приложения занудство – благо :)
Мне кажется важным, что фреймворк не только не мешает реализации бизнес-логики, но и стимулирует программистов быстрее выводить в продакшен разрабатываемые возможности. Незачем полировать фреймворк до блеска – лучше довести до идеала код бизнес-логики. Сравните современную Java EE или Spring с дедовскими версиями J2EE – думаю, сразу поймете, о чем я.
Jakarta EE должна развиваться в том же русле и, соответственно, сосредоточиться на спецификациях, которые позволят разработчикам максимально быстро реализовывать бизнес-логику.
Соглашения по конфигурации
В Java EE сведена к минимуму конфигурация, необходимая для определения типичного корпоративного приложения. В большинстве практических ситуаций соглашения работают прямо из коробки, никакой конфигурации соблюдать не требуется. Так, больше не нужно никаких XML-файлов, чтобы сконфигурировать простое приложение для Java EE. Другой пример – в JAX-RS предоставляются действующие по умолчанию коды HTTP-откликов, соответствующие возвращаемым значениям методов JAX-RS.
Java EE действительно обладает достаточной гибкостью, позволяющей модифицировать поведение и реализовать более сложные сценарии; однако, соглашения по этому поводу нет.
Jakarta EE должна и далее превращать простое в легкое, а сложное – в возможное.
Интероперабельность спецификаций
Jakarta EE должна продолжать и расширять интероперабельность спецификаций. В Java EE соблюдаются существующие спецификации и та присутствующая в них функциональность, которая уже стала частью стандарта.
Разработчики могут рассчитывать на то, что разрозненные спецификации будут хорошо взаимодействовать друг с другом, и никакой конфигурации при этом не потребуется. Стандарты требовали: если среда времени выполнения поддерживает как спецификацию A, так и спецификацию B, то A + B должны взаимодействовать друг с другом. Примеры: валидация компонентов, JAXB или JSON-B могут применяться в классах ресурсов JAX-RS, и никакой дальнейшей конфигурации не требуется.
Внедрение зависимостей и CDI
Конечно, нежелательно, чтобы в Jakarta EE заново изобретались те вещи, которые уже существуют – например, внедрение зависимостей, относящееся к CDI. Желательно, чтобы спецификации использовали и акцентировали сильные стороны JSR 330 или, если потребуется, CDI.
Свежий пример — использование
UriInfo
из JAX-RS в методах ресурсов. Аннотация @Inject
пока еще не поддерживает внедрения методов такого типа. Программисту тем удобнее работать, чем больше он полагается при этом на универсальный механизм.Другая конкретная мера такова: в спецификациях должны предоставляться поставщики CDI, а при необходимости – квалификаторы typesafe для типов, которые потребуется создавать. Так, на настоящий момент экземпляр клиента JAX-RS можно получить только программно, через API
ClientBuilder
. Производители и квалификаторы упрощают работу программиста, поскольку обеспечивают декларативные определения. Декларативные подходы
При всем этом API Java EE серьезно полагается на декларативный подход, при этом используется инверсия управления. Таким образом, разработчики не вызывают функционал напрямую; за вызов функционала отвечает контейнер, при этом мы опираемся на определения кода. Примеры (из наиболее современных спецификаций) — JAX-RS, JSON-B или CDI.
Jakarta EE не только предоставляет более исчерпывающие программные API, но и должна в дальнейшем способствовать применению декларативных определений и инверсии управления.
Стратегии развертывания
Характернейшая особенность (а на мой взгляд – и большое преимущество) Java EE заключается в том, что предлагаемая здесь модель развертывания, в которой проблемы бизнес-логики отмежевываются от реализации. Разработчик программирует исключительно под API, который не входит в состав артефакта развертывания и реализуется контейнером приложения.
Такие компактные артефакты развертывания упрощают и ускоряют доставку программы, в том числе, сборку, публикацию и развертывание как таковое. Также они совместимы с уровнями контейнерной файловой системы, используемой, например, в Docker. В процессе сборки необходимо всего лишь пересобрать или повторно передать изменившиеся элементы.
В идеале артефакты развертывания должны содержать только бизнес-логику и ничего кроме; реализации времени исполнения и потенциально добавляемые сторонние библиотеки доставляются на более низком уровне, например, в серверных библиотеках приложения, добавленных на предыдущем этапе сборки контейнера.
В Jakarta EE развернутые артефакты также должны считаться сущностями первого класса. Возможно, там появится возможность еще сильнее ужать среду времени исполнения на основе спецификации, требуемой приложением. Однако, в Jakarta EE предполагается уделять максимум внимания бизнес-логике и продуктивности разработчика, а доводка времени исполнения уже вторична.
Тестируемость
Применяя вышеперечисленные принципы, особенно отдавая предпочтение декларативному программированию и внедрению зависимостей, мы совершенствуем тестируемость бизнес-кода. Таким образом, разработчики могут напрямую инстанцировать объекты в тестовых сценариях, поскольку теперь не требуется наследовать классы API или вызывать неудобный функционал, который ранее потребовалось бы сымитировать.
Однако, в Jakarta EE требуется серьезно доработать стандартизацию интеграционного тестирования на уровне кода, так, чтобы оно не зависело от производителя. Ранее именно с этим приходилось иметь дело при работе с Arquillian. В реальных проектах был бы полезен такой стандарт, который позволяет объявлять только сценарии тестового развертывания и вызывать функционал для одного или нескольких компонентов. Ранее я уже писал, что не считаю чрезмерно важным интеграционное тестирование на уровне кода, например, при выполнении приложения во встроенных контейнерах. Однако, если стандартизировать интеграционные тесты на уровне кода, это явно даст положительный эффект.
Заключение
Думаю, неслучайно API Java EE так широко применяются в реальных проектах: эти API хорошо продуманы и спроектированы в соответствии с четкими принципами, благодаря которым удалось унифицировать даже не единственную спецификацию, а целую платформу. Они позволяют пользоваться сразу несколькими спецификациями, выдержанными в едином духе. Здесь удалось избавиться от искусственных препятствий, только усложняющих работу программиста – поэтому, полагаю, вся enterprise-разработка стала гораздо приятнее.