Ленивые вычисления для реализации функциональной архитектуры
May 7, 2022
Микропост в догонку к посту о книге.
Вкратце напомню суть функциональной архитектуры - ввод-вывод надо утаскивать на границы системы. В идеале это значит, что у вас код метода сервиса приложения состоит из трёх строго разделённых частей: чтение данных, бизнес-логика, запись данных. При том эти части идут линейно - в идеале метод не должен содержать условий.
Это делает бизнес-логику максимально простой для понимания, применимой в многопоточной среде и чрезвычайно просто тестируемой.
Однако не всегда такое разделение даётся легко и/или без ущерба производительности. Например, если есть две операции чтения и одна зависит от другой.
Например, у вас есть хранилище изображений с метаинформацией, и операция их сжатия. Но для некоторых изображений сжатие запрещено. "Беспринципно" этот код можно реализовать так:
Чтобы сделать эту реализацию функциональной, надо сначала определить весь ввод, потом бизнес-логику, потом вывод. Почему это важно - отлично расписано в книге.
Но если мы сделаем загрузку файла, до проверки на возможность его компрессии - это ударит по производительности. И тут нам приходит на помощь ленивая загрузка:
Теперь для того чтобы протестировать бизнес-требование "Система не должна позволять сжимать изображения, для которых запрещено сжатие" мы можем написать чистый юнит тест, не заморачиваясь на сетап хранилища файла, Spring-а и моков:
Вот так легко и просто можно реализовать функциональную архитектуру, которая открывает путь к простому разработческому счастью - набору тестов, которые легко писать, не препятствуют рефакторингу и отлавливают баги.