Комментарии 37
Как это юнит-тестировать?
Ну, в этом случае юнит-тесты вполне возможны:
- при полиморфизме: тестируем каждый класс отдельно;
- при функциональном стиле: тестируем каждую функцию;
- при использовании шаблонов - тестируем правила по отдельности или их в комбинации.
Плюсом при таком походе будет меньше моков и более чёткие зависимости, более стабильные тесты (нет сложных ветвлений);
А минусом будет то, что надо больше мелких тестов, зато они проще.
А в целом, можно сказать, что тесты станут более простыми и надёжными.
Для юнит тестов нет разницы, сделали ли вы через optional или if else они тестируют возвращаемое значение.
Тернарный оператор перестал считаться условным?!
На данный момент боремся с тремя озвученными: if-else, switch :-)
Так это синтаксический сахар к условному.
Тут вся статья буквально про "как спрятать if". Взятие элемента из Map будет сопровождаться кучей проверок, ровно как и функциональный filter, даже если делать дичь как в TS и запекать полиморфизм. то на уровне байткода там все равно окажется какой-нибудь jne
. А я то уж понадеялся, что щас про branchless программирование покажут что-нибудь.
На зло маме отморожу уши. А зачем? Читабельность никакая, ресурсов тратит больше.
Здесь больше речь о возможностях как таковых. А как их использовать и использовать ли - второй вопрос ;-)
В примере с оптионал вполне повышает читабельность. Возьмите пример простого кода, добавьте в него все пропущенные проверки на нул и сравните. Последовательные операции намного легче читать, чес скакать по дереву условий.

Без условных операторов, серьёзно? Я в этом коде вижу как минимум три условия: isValid
, isCurrentDayData()
, orElse()
.
выбор конкретной реализации может быть передан «фабрике» — что избавляет нас от необходимости реализации проверок в основном коде.
Дженерики использовать не судьба? Паттерн матчинг, в конце концов?
Зачем вообще всё это? Отказ от if/switch
– это религия какая-то? В некоторых случаях это действительно приводит к трудночитаемому коду, но приведённые примеры к таковым не относятся.
P.S. Использование скриншотов вместо вставок кода – плохая практика, затрудняет цитирование.
Напишите как вы видите более лучшую реализацию для конкретно этого случая, мы с удовольствием ознакомимся с вашим предложенным подходом ;-)
P.S. Без всяких подколов - реально интересно. "Век живи- век учись".
Напишите как вы видите более лучшую реализацию для конкретно этого случая
Я для всех случаев вижу, что каждое средство языка должно использоваться на своём месте, и не должно быть никаких религиозных догм типа полного отказа от if/switch
– это приводит к ненужному усложнению кода.
Согласен - об этом в самом конце тоже сказал. Но если возможно реализовать лучше - напишите сюда, если есть время - думаю, нам всем будет интересно;-)
Без условных операторов, серьёзно? Я в этом коде вижу как минимум три условия:
isValid
,isCurrentDayData()
,orElse()
.
Только это методы, а не операторы.
Во первых, нет: там тернарный оператор, который есть просто альтернативная форма записи if/then/else
. Во-вторых, такое упрятывание условных ветвлений не улучшает, а ухудшает читаемость кода.
Метод который используется как условие тернарного оператора не перестаёт быть методом.
На счёт упрятывания не совсем вас понимаю. Такие цепочки читаются строка за строкой. Там сложно, что-то спрятать. А читая дерево операторов можно волне пропустить ветку, или отсутствие ветки.
Что мы здесь видим: существует карта
Map
, заполненная ключами (например,source_1
) и значениями, где в качестве значений выступают конструкторы соответствующих классов.
Стоит добавить, что такой подход неплохо показывает себя в продакшене, где есть множественные реализации чего-либо вкупе с каким-нибудь DI-контейнером (тот же Spring). Только вместо строковых литералов безопаснее использовать enum.
Есть ощущение, что все это "концептуальность ради концептуальности".
В реальной жизни постоянно приходится сталкиваться с достаточно сложными условиями - "если А лежит в диапазоне от ... до ..., при этом Б меньше чем ... и С больше чем...". Пытаться все это сделать без if? Ну, наверное, можно. Но получится многословно и неочевидно - если вам достанется на доработку такой чужой код, то понять что именно он делает будет сложновато - вам придется все эти уровни абстракций копать до самого дна - "а вот этот isValid - он вообще как валидирует? А мне по новым условиям нужно чтобы оно иначе валидировало - куда лезть и годе править?"
Ну и есть стойкое ощущение что все условные операторы просто прячут куда-то вглубь абстракций и внешних зависимостей чтобы потом гордо сказать "я не пользуюсь if" (при этом забывая сказать что "я пользуюсь тем, что пользуется if").
Функциональное программирование представляет собой такой подход, при котором программа строится только на использовании функций, которые передаются как аргументы, возвращаются из других функций
А где та самая первая функция, которая не вызывает других функций, а делает все сама? Является ли она частью функциональной парадигмы, или это процедурность, лежащая фундаменте всего остального?
Ну тут спорно, сложные конструкции из вложенных ифов понимать сложнее, чем несколько абстракции. Другое дело, что баланс нужно соблюдать и не наворачивать абстракции, если условия плюс-минус простые.
Сложные конструкции вообще сложно понимать :-) Абстракции плохи тем, что когда нужно понять логику работы программы (а в жизни неоднократно приходилось сталкиваться с весьма и весьма мудреной и неочевидной бизнеслогикой), приходится работать одновременно с несколькими исходниками, отслеживая каждый вызов "до самого дна".
А уж когда нужна аналитика типа "кто использует этот модуль" (на предмет оценки рисков и объема регресс-тестов при его изменении), а там начинается - этот модуль используется модулем А, который вызывается из модуля Б, а тот задействован в модуле В...
Но не суть.
Простота чтения кода - это не про использование или не использование if. Это про стиль. Многовложенные if, конечно ничуть не проще в понимании чем пирамида многоуровневых абстракций... Так что тут стоит использовать все средства, которые могут облегчить читаемость кода.
Смотрю на зоголовок:
"Программирование без условных операторов"
Смотрю в статью, там условный оператор.
Штош.....
Статья о том как уменьшить читаемость и спрятать/замаскировать условные операторы
При фразе "программирование без условных операторов" ожидал увидеть статью про информационную безопасность, и защищённые от взлома алгоритмы, где неиспользование условных переходов усложняет исследование.
А получил "спрячем все ифы в метод IfElse и назовём это функциональным стилем".
Наименее разочаровывает пример про полиморфизм, хоть и обфусцирует исходный алгоритм.
Избавиться от условий.. чтобы что? Ради академического интереса - ладно. Ради быстродействия? Нет. Идея для следующего опыта - исследовать smali различных подходов. Там видно будет во что (в какие инструкции) превращается иф, елс и свитч. Сам, как писатель на джавах, могу сказать что этот язык запросто может избаловать и превратить простой проект в вавилонскую башню. Особенно заметно по ждунам, которые начинаются модных авторов и начинают изобретать собственные архитектуры. Могу посоветовать параллельно изучать другой, более низкоуровневый язык. Это помогает "размылить" взгляд и начать думать логически, а не обмазываться фабриками и полиморфизми. Можно Си, причем лучше под микроконтроллеры (хоть есп, хоть ардуины), они научат в сложных моментах экономить такты процессора и оперативную память.
Как программист графики, с большим интересом ткнул на статью.
В видеокартах ветвление усложняет выполнение задачи - рабочие треды ядра заканчивают одну ветвь, и только потом приступают к другой. Причëм это не распараллеливается. Так что для крипты/игр/ИИ задача более чем актуальная.
Подумал, будут хитроумные трюки с битмасками, адресами памяти и побитной логикой.
Нашëл какую-то джавную ООП ересь, теперь глаза с мылом придëтся мыть
У статьи неправильное название, правильное название что то вроде - как писать на фп.
От условных операторов вы толком и не избавились. Абстракции функциями все так же используют условный оператор под капотом, вы лишь сделали их невидимыми. Кроме как повысить читаемость (даже тут спорно, повышает ли) и научного интереса, вы ничего не достигли и у в реальной жизни такой код писать никто не будет. Ракеты вы на этом не построите, ядра ос тоже нет, лёгкую прошивку железа тоже будет сложно.
Объяснение абстрактных фабрик и полимоофма и у вас вышло лучше, чем вся статья. В остальном - сомнительно.
в реальной жизни такой код писать никто не будет. Ракеты вы на этом не построите, ядра ос тоже нет, лёгкую прошивку железа тоже будет слсложно
Да нормальный код. Понятно, что примеры упрощенные, но такой подход широко применяется. Не все строят ракеты и пишут для встраиваемых систем. Для энтерпрайза такие вещи вполне обыденные.
Конечно, никто не отказывается от условных операторов, но иногда подобные замены сильно повышают читабельность и расширяемость. Делать фабрику с десятками case - такое себе решение, а с мапой уже выглядит получше.
Использование Optional тоже хорошая штука, когда нужно сделать цепочку проверок и преобразований или вернуть результат, над которым можно сразу произвести такую цепочку без явных ветвлений.
Насколько я понял, в основном претензии к автору за громкий заголовок, хотя, если его рассматривать, как фигуру речи, описанные подходы вполне обычные и широко распространены
Почему фабрика не сделана статическим классом?
Ифэлсефобия в тяжёлой форме )
вот бред
Map конечно хорошо, но достаточно было обычного массива с enum для индексов. Все таки внутри реализации map if-ов будет предостаточно. Это как спрятать их внутри другой функции (тоже самое и с полиморфизмом). + в кеш проца легло бы отлично
Программирование без условных операторов