Java: fill the gaps
12.6K subscribers
7 photos
217 links
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк

🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt

Комплименты, вопросы, предложения: @utki_letyat
Download Telegram
Чистая архитектура. Главы 3-5

Продолжаем спидран по Clean Architecture Роберта Мартина.

⭐️ Глава 3. Парадигмы программирования ⭐️

определяют способы написания и организации кода. Их 3:

▫️ Структурная - ход программы описывается явно через условия и циклы. Используется для описания алгоритмов
▫️ Обьектно-ориентированная - программа описывается как взаимодействие объектов. Используется полиморфизм, ход работы не всегда очевиден
▫️ Функциональная - базируется на неизменяемости

⭐️ Глава 4. Структурное программирование ⭐️

Код делится на небольшие функции, которые можно протестировать. Но если тесты проходят - не факт, что программа работает корректно. Большую часть главы занимают истории, как Дейкстра боролся против goto и пытался математически доказать корректность программ.

⭐️ Глава 5. Обьектно-ориентированное (ОО) программирование ⭐️

Роберт рассуждает, что полезного и нового предлагает ООП

▫️ Инкапсуляция - не уникальна для ООП, плюс в современных языках не решает свою задачу.

Исходная цель инкапсуляции - скрыть данные и дать пользователю ограниченный набор методов.

В С (предшественник С++) определение функции и реализация разнесены по разным файлам, там инкапсуляция нормальная. В современных ОО языках инкапсуляция слабая. Нет разделения на определение и реализацию. Чтобы посмотреть, что умеет класс, надо зайти в класс, и тут открывается вся его внутрянка. Детали реализации как на ладони.

(мысль интересная, но с текущими IDE это не актуально. Выпадающие списки методов делают большой вклад в сокрытие сложности)

▫️ Наследование - всего лишь переопределение переменных/функций в ограниченном контексте. Добавочной ценности для архитектуры нет.

▫️ Полиморфизм легко и безопасно реализован в ОО языках, и в этом его главная ценность. Благодаря полиморфизму расцвел концепт инверсии зависимостей.

Дальше автор объясняет dependency inversion. Тут меня знатно побомбило.

DI - базовый кирпичик и первый шаг к чистой архитектуре. Это самая важная часть раздела. И она объяснена очень плохо:
▪️ Роберт вводит 2 типа стрелочек: source code dependency и flow of control. Не объясняя, что это такое
▪️ Рисует схему, где стрелочки идут вместе
▪️ Добавляет в схему ещё один квадрат (интерфейс) и поворачивает одну стрелку в другую сторону

На этом всё. Ни одного примера с кодом, только квадратики и стрелки. Этого недостаточно, чтобы каждый читатель понял, что нужно делать и в чём инверсия. Просто добавить интерфейс к каждому классу? Service и ServiceImpl это и есть тот самый power move?

Особенно дико такое объяснение выглядит на контрасте с менее важными темами. Рядом есть детальный разбор
✔️ разницы инкапсуляции в С и С++
✔️ как в С (язык без классов) можно имитировать наследование
✔️ как работают атомики в Clojure

Всё это разжевано гораздо подробнее, чем DI🤦

В 11 главе Роберт сделает второй заход в dependency inversion, но (спойлер) всё останется на уровне "просто добавь интерфейс". Это рекомендации по форме, но не по содержанию.

Интерфейсом может быть не только дополнительный квадратик, но и набор публичных методов класса. Чем больше этот набор скрывает детали реализации и упрощает работу с классом, тем лучше. И чтобы уменьшить связность, не обязательно множить сущности.
👍6425🔥17👎6
Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфигурация ниже. Настройки прогона тестов стандартные. Сколько времени займет выполнение этих тестов?
@SpringBootTest
public class UserIT{...}

@ActiveProfiles("test")
@SpringBootTest
public class BidProcessingIT{...}

@SpringBootTest(properties = {
"user.rebalance.enabled=true"
})
public class RebalanceAccountIT{...}

@ActiveProfiles("test")
@SpringBootTest
public class AccountProcessingIT{...}
7
Как переиспользовать контекст в интеграционных тестах

Сегодня расскажу базовый минимум для написания интеграционных тестов в Spring: как работать с контекстом, чтобы тесты шли не по 2 часа.

В спринге интеграционным тестом называется тот, для которого нужен контекст. Контекст - это набор бинов, свойств, профилей и тд. Поднимать его для каждого теста долго, поэтому Spring по возможности переиспользует созданные ранее контексты.

Если в коде теста какой-то бин помечен @MockitoBean, @MockitoSpyBean или @TestBean, Spring создает для него прокси. Получается уникальный контекст, который нужно поднимать отдельно и нельзя в дальнейшем переиспользовать.

К новому контексту приводит переопределение свойств, указание профиля, конфигурация MockMvc и тд

Ответ на вопрос перед постом - прогон тестов будет занимать чуть больше 6 минут, потому что формируется 3 контекста. Для тестов BidProcessingIT и AccountProcessingIT используется один контекст.

🤔 Как оптимизировать выполнение тестов?

Популярный прием, который помогает зафиксировать контекст - базовый класс с тестовой конфигурацией. В базовом классе настраивается тестовый конфиг, тестконтейнеры, решается вопрос с секьюрити, наполнением и очисткой БД и тд
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(…)
@TestExecutionListeners(…)
@ActiveProfile("test")
// куча других аннотаций
public abstract class BaseIntegrationTest {
// тестконтейнеры
// заглушки
}

Остальные классы наследуются от базового:
class UserIT extends BaseIntegrationTest {
@Autowired
  private MockMvc mockMvc;
  @Test
  public void shouldCreateUser() {…}
}

При такой схеме важно следить, чтобы в наследниках не заменялись бины, свойства и тд. Иначе для них будет создан новый контекст.

На практике редко используется один базовый класс, чаще это иерархия под разные случаи. При грамотном проектировании и сознательности разработчиков интеграционные тесты выполняются за адекватное время даже для больших проектов👌
61👍37🔥24👎2
Clean Architecture: отзыв на книгу

Наконец-то дочитала книгу Clean Architecture Роберта Мартина. Делюсь отзывом!

Начну с художественной составляющей🧚‍♀️

Это самая "авторская" книга по архитектуре/разработке, которую я читала. Обычно в технических книгах автора не видно, истории описываются нейтрально, структура чёткая и максимально работает на раскрытии темы.

В Clean Architecture ситуация другая, автор выражен очень ярко. Внутренний голос при чтении становится хриплым и дедовским👨‍🦳 Хотя Мартин кажется не самой приятной личностью, мне нравится подобный стиль в технической литературе, если он не идет в ущерб смысловой части.

Перейдём к содержанию. Кратко: "Соблюдай SOLID, не смешивай бизнес-логику с БД и UI. Что конкретно делать - не скажу, но расскажу байку из 70-х".

В книге есть здравые мысли, но оформлены они очень плохо. Не только с точки зрения практики (мало примеров и конкретики), но и в теории. Много отвлечений, бывает, что тезисы чётко не сформулированы, а объяснение брошено на полпути.

Наглядный пример — глава 33, Case study. Автор обещает, что сейчас мы обобщим наши знания и спроектируем систему с чистой архитектурой. Описывает пачку бизнес-требований и use-case диаграмму.

Я уже сидела в предвкушении, что сейчас увижу образцовый SOLID и Clean Architecture. Как ловко Мартин разберётся с бизнес-требованиями и организует систему.

Итоговую схему приложу в комментах. Для каждой роли там сделан набор квадратиков: Views, Presenters, Interactors, Controllers. Каждый Interactor общается с БД. На этом всё.

Многие главы вызывают похожие эмоции. Например, глава 21, Screaming Architecture. Основная идея: структура системы должна отражать, какие бизнес-функции она реализует.

Есть ли в главе хоть один пример? Нет. Понятно ли по схеме в Case Study, какие сценарии реализует система? Тоже нет.

Не раз возникала мысль, может я читаю версию-черновик? Допустим, автор на своей волне и излагает материал, как чувствует. Но где ревьюеры и редакторы? Добавить структуру, формулировать мысли чётче, переписать примеры на современные технологии, вычеркнуть неуместные истории — где эти очевидные правки?

Интересный факт — главу о том, как раскидать код по папкам, написал другой человек. И как по-другому написана эта глава! Понятные тезисы, детально описанные схемы. Огромный контраст со стилем Мартина. Будто просыпаешься от сна и вспоминаешь, как выглядит нормальная техническая книга.

Что касается меня — на свои вопросы к чистой архитектуре я не нашла ответов и не узнала ничего полезного. Книгой разочарована, не понимаю, для кого вообще она написана. Но рада, что удалила её из списка "прочитать", она там висела несколько лет

Общая оценка: 1/5

Самые полезные главы:
▫️ Главы 7-11: SOLID. Чтобы ознакомиться с оригинальными формулировками и составить своё мнение
▫️ Глава 22: Clean Architecture. Набор признаков чистой архитектуры

Ещё прочитала книгу Get your hands dirty on clean architecture. Обычно её рекомендуют на запрос "посоветуйте что-нибудь по чистой архитектуре". Отзыв на неё будет в следующем посте🌸
91🔥50👍32👎13
Get Your Hands Dirty on Clean Architecture: отзыв на книгу

Когда я подняла тему чистой архитектуры, на меня посыпались рекомендации изучить книгу Get Your Hands Dirty on Clean Architecture, автор Tom Hombergs. Прочитала, делюсь отзывом!

Сердце книги — сервис перевода денег с одним методом. Этот сервис автор реализует в гексагональной архитектуре (она же "порты и адаптеры"), подробно объясняя каждый шаг и возможные варианты. Получается приятный баланс теории и практики.

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

Помимо реализации сервиса, поднимаются такие темы (в скобках укажу позицию автора):
▫️ Чем плоха слоистая архитектура Controller-Service-Repository (всё опирается на структуру БД, код в сервисах становится сильно связанным месивом)
▫️ Как связаны чистая и гексагональная архитектуры (чистая более абстракна, гексагональная - вариация с портами и адаптерами)
▫️ Виды валидации (техническая валидация и уровне бизнес правил)
▫️ Где открывать и закрывать транзакции (в use case)
▫️ Какие тесты и для чего писать (юниты для бизнес логики, интеграционные для контроллеров и репозиториев + сквозной тест для основных сценариев
▫️ Как соблюдать границы слоев по мере развития проекта (модификаторы доступа, ArchUnit, Maven/Gradle модули)
▫️ Можно ли упрощать архитектуру? Пропускать слои, использовать доменные сущности в контроллерах? (зависит от сложности сервиса и договоренностей внутри команды)
▫️ Для каких проектов подойдёт чистая архитектура? (со сложной доменной логикой)

Основные минусы книги:

1️⃣ Неподходящий формат

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

2️⃣ Сомнительный use-case

В проекте заявлен всего один use-case, и в книге даже нет реализации. Есть разные способы распределить код между доменом, сценарием и application слоем. На примере перевода денег можно показать разные подходы. Но этого нет.

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

⭐️ Общая оценка: 3/5 ⭐️

Для кого: для тех, кто только знакомится с чистой/гексагональной архитектурой. Кто увидел схему с кружочками и задумался "а как при этом выглядит проект". Задачу знакомства книга решает отлично, но написать что-то серьёзное на этой базе вряд ли получится.

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

96 человек отметили, что у них с чистой архитектурой всё чудесно складывается на практике, так что надежда получить позитивный опыт ещё жива😊
57👍26👎5