tgoop.com/java_fillthegaps/526
Last Update:
Pattern matching: зачем?
Последние годы в джаву активно добавляется группа фич на тему pattern matching.
Тагир Валеев из Intellij IDEA в этом докладе рассказывает, какие это сложные фичи, как много челленджей стояло перед командой разработки. Но не говорит, зачем он вообще нужен.
Архитектор java Brian Goetz пишет, что pattern matching — не просто синтаксический сахар, а движение в сторону data oriented programming. Но это слабо применимо к большинству корпоративных систем, где доминирует ООП и изредка встречается функциональное программирование.
Большая часть моих знакомых считает паттерн матчинг "стрелкой вместо двоеточия в свиче":)
Так что сегодня расскажу, для каких задач пригодится pattern matching. В следующем посте обсудим реализацию в java.
Формат входных данных в энтерпрайзе обычно чётко определён. Если входящее сообщение не подходит по формату — это ошибка со стороны клиента.
Но бывает, что система работает со множеством источников данных, и выделить общий формат очень сложно.
Например, вы парсите чужие сайты/документы/дампы и достаёте оттуда что-то полезное. Знаю один проект, где бизнес-данные вытаскивают из логов(!) другой системы🤯
В итоге входные данные выглядят как [Object, Object, Object]
.
Паттерн — схема того, что мы ищем. Паттерн для поиска координат может выглядеть так:
▫️ [Double, Double]
— ищём массив из двух чисел с плавающей запятой
▫️ [(-90;90), (-180,180)]
— массив с двумя числами в указанных диапазонах
Дальше идём по набору данных и проверяем их на соответствие паттерну.
Традиционно для такой задачи используется связка if + instanceOf
. Вариант рабочий, но читаемость ужасная.
Вот что нужно написать, чтобы проверить, является ли координатами массив [Object, Object] data
:
if (data.length == 2 && data[0] instanceOf Double && data[1] instanceOf Double) {В pattern matching многие проверки убираются под капот, и код выглядит симпатичнее:
double n = (Double) data[0];
double e = (Double) data[1];
if (n ≥ -90 && n≤ 90 && e ≥ -180 && e ≤ 180) {
// что-то делаем
}
}
switch(data) {Близкий родственник паттерн матчинга — регулярные выражения. Строка — это набор символов, внутри этого набора ищутся паттерны. Можно сделать ту же работу через if, но регулярка удобнее. Плюс в строке элементы однородные (символы), а паттерн матчинг работает с разными типами данных.
case [(-90; 90), (-180, 180)]:
// что-то делаем
}
Ещё пример:
double discount = switch(transaction) {Здесь ищем список из 5 элементов, где первый — строка "vip", второй и пятый — число. Если нашли — можно сразу работать с полем
case ["vip", Long, _, _, Double sum] → sum*0,9
case _ → 0
}
sum
. Если не нашли — используем паттерн по умолчанию _
С if-ами эта конструкция будет гораздо объёмнее
Резюме
✅ Pattern matching нужен, когда мы пытаемся найти что-то знакомое в слабо- или неструктурированных данных.
✅ Большинство
instanceOf
и if
отправляются под капот, и мы получаем более компактный код. ✅ Разумеется, применить pattern matching можно и в других сценариях, но здесь видится наибольший профит в корпоративном царстве ООП.
В следующем посте распишу возможности pattern matching конкретно в джаве.
Спойлер:
BY Java: fill the gaps
Share with your friend now:
tgoop.com/java_fillthegaps/526