Фитнес-функции и их роль в эволюции архитектуры на Java.
https://t.me/javatgВ данной статье мы рассмотрим понятие фитнес-функций (функций приспособленности) и приведем ряд простых примеров. Изучив материал, вы узнаете о назначении этих функций и свежим взглядом посмотрите на тестирование требований к вашим проектам.
Понятие фитнес-функций
Фитнес-функции измеряют степень соответствия архитектуры поставленной цели. Это наш ориентир в процессе эволюции системы.
Архитектура ПО учитывает такие важные требования, как производительность, надежность, безопасность, работоспособность, стандарты оформления кода и т. д.
Например, мы пишем тесты или метрики для соответствия необходимым критериям. Выдвигается бизнес-требование: все сервисы должны откликаться в течение X мс. В этом случае разрабатывается тест, который измеряет время ответа. Если результат превышает данное значение, то тест не пройден.
Каждый новый сервис должен удовлетворять установленным тестовым критериям. Таким образом мы постоянно получаем обратную связь о процессе разработки и его соответствии плану.
Применение фитнес-функций
Целесообразно определять фитнес-функции на ранних этапах разработки ПО. Каковы важнейшие критерии продукта? Как правило, участники проекта и бизнес-аналитики предоставляют спецификацию. Требования разнятся в зависимости от производственной отрасли. Например, в банковской сфере решающую роль играют стабильная производительность и безопасность.
Стандарты архитектуры постоянно развиваются. Фитнес-функции помогают разбить сложную систему на более мелкие части, тем самым способствуя безопасному внесению изменений в ПО и обнаружению проблем на ранних стадиях.
Примеры фитнес-функций и инструменты
Получив необходимые критерии от сторон-участников, интегрируем их во фреймворк тестирования и рассматриваем возможность включения тестов в процесс конвейера CI/CD.
Скорее всего, вы уже работали с модульными тестами, которые обеспечивают соответствующее качество кода. Рассмотрим другие нефункциональные требования, такие как масштабируемость, производительность и иные аспекты архитектуры.
Тесты для проверки ограничений архитектуры
Напишем тест для проверки ограничений архитектуры.
Рассмотрим фитнес-функцию, определяемую на техническом уровне архитектуры, для управления зависимостями между компонентами. Так, для Java используется инструмент под названием ArchUnit. Он анализирует зависимости между пакетами и классами, слоями и срезами, а также проверяет на наличие циклических зависимостей и т.д.
Тесты выполняются как тесты JUnit. Они не позволяют разработчикам нарушать принципы архитектурного дизайна. Если кто-то случайно отправит на рассмотрение не соответствующий требованиям код, то сборка завершится ошибкой, и разработчик вовремя обнаружит проблему.
Проверим, что класс контроллера вызывает только защищенные методы:
@ArchTag("example") @AnalyzeClasses(packages = "com.tngtech.archunit.example.layers") public class ControllerRulesTest { @ArchTest static final ArchRule controllers_should_only_call_secured_methods = classes().that().resideInAPackage("..controller..") .should().onlyCallMethodsThat(areDeclaredInController().or(are(annotatedWith(Secured.class)))); @ArchTest static final ArchRule controllers_should_only_call_secured_constructors = classes() .that().resideInAPackage("..controller..") .should().onlyCallConstructorsThat(areDeclaredInController().or(are(annotatedWith(Secured.class))));
Тест контроллера с помощью ArchUnit позаимствован из кода по ссылке.
Тесты для проверки дизайна архитектуры
Если вы применяете многоуровневую архитектуру ПО, можете добавить тесты ArchUnit и с их помощью убедиться, что дизайн не нарушен:
@ArchTest static final ArchRule layer_dependencies_are_respected = layeredArchitecture() .layer("Controllers").definedBy("com.tngtech.archunit.example.layers.controller..") .layer("Services").definedBy("com.tngtech.archunit.example.layers.service..") .layer("Persistence").definedBy("com.tngtech.archunit.example.layers.persistence..") .whereLayer("Controllers").mayNotBeAccessedByAnyLayer() .whereLayer("Services").mayOnlyBeAccessedByLayers("Controllers") .whereLayer("Persistence").mayOnlyBeAccessedByLayers("Services");
Тест многоуровневой архитектуры позаимствован из кода по ссылке.
Данный тест гарантирует, что доступ к указанным слоям предоставляется только предусмотренным из них.
Тесты для проверки архитектуры и работоспособности
Вы можете измерить сочетание архитектурных и функциональных характеристик. Для облачных сред применяется инструмент Chaos Monkey. Его разработали инженеры Netflix для тестирования отказоустойчивости AWS.
Он произвольно нарушает порядок работы: увеличивает время задержки, прерывает процессы и т.д. Выявление неполадок гарантирует, что разработчики обеспечат устойчивость сервисов к конкретным сбоям.
Тесты для проверки безопасности
Для проверки безопасности можно воспользоваться технологией статического тестирования безопасности приложений (англ. Static Application Security Testing, сокр. SAST) или инструментами сканирования образов контейнеров. Вы можете предотвратить использование образа контейнера с известными уязвимостями. Например, такие инструменты, как JFrog Xray, рекурсивно сканируют все слои в контейнере.
Заключение
Применение фитнес-функций гарантирует соответствие ПО требуемым стандартам архитектуры. Разбивая ПО на небольшие компоненты, вы упрощаете внедрение новых изменений. Фитнес-функции постоянно предоставляют обратную связь о процессе разработке.