Сопоставление шаблонов 💖 таблицы решений

Случалось ли вам писать массивный вложенный оператор if и думать: 🤮? Если да, то, возможно, этот пост для вас.

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

Это дерево решений представляет собой бизнес-логику, определяющую, какой тип апострофа следует использовать (или не использовать) в той или иной ситуации. Нередко эксперты по доменам иллюстрируют свою бизнес-логику с помощью дерева решений, подобного этому.

Деревья решений можно напрямую сопоставить с моим предпочтительным способом отображения такого типа информации — таблицей решений. В таблице решений мы берем узлы дерева вопросов и располагаем их в верхней строке. Затем мы создаем дополнительный столбец в правой части таблицы и заполняем его «действиями», которые мы должны предпринять, — это листовые узлы нашего дерева решений. Затем мы заполняем все возможные варианты ответов на наш вопрос, в нашем случае истинный (✔️) ложный (❌) или любой из них (🤷).

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

Множественное число? Одиночная буква? Аббревиатура?
🤷 🤷 См. таблицу поссессивов
✔️ ✔️ 🤷 Апостроф + s
✔️ ✔️ Апостроф + s
✔️ Без апострофа

Таблица множественного числа

Обладающий? Это «it»? «оно есть» или «оно имеет»? имя, оканчивающееся на s? имя во множественном числе? заканчивается на s?
🤷 🤷 🤷 🤷 🤷 См. таблицу сокращений
✔️ ✔️ ✔️ 🤷 🤷 🤷 Апостроф + s
✔️ ✔️ 🤷 🤷 🤷 Без апострофа
✔️ 🤷 ✔️ 🤷 🤷 Апостроф в конце
✔️ 🤷 ✔️ 🤷 Апостроф в конце
✔️ 🤷 ✔️ Апостроф в конце
✔️ 🤷 Апостроф + s

Таблица поссессивов

Сокращение? С презенсом? с глаголом?
🤷 🤷 Без апострофа
✔️ ✔️ ✔️ Использовать апостроф
✔️ 🤷 Использовать апостроф
✔️ ✔️ Без апострофа

Таблица сокращений

Если вы работаете с экспертом по доменам, который любит использовать деревья решений, попросите его перейти на использование таблиц.

Итак, у нас есть логика для нашего домена, теперь как нам реализовать ее в коде? Мы можем написать довольно большой вложенный оператор if. Или же, если нам дано дерево, почему бы не представить эту информацию в виде дерева? Мы можем создать древовидную структуру с узлами, ребрами и листьями и смоделировать ее напрямую.

Эти варианты могли бы работать, но есть пара проблем. Если наш эксперт по доменам вернется и скажет нам, что бизнес-логика изменилась, и предоставит новое дерево. Не так-то просто перевести новую логику в код с помощью любого из этих двух методов. Нет прямого сопоставления, и в целом бывает трудно взглянуть на большой вложенный оператор if (при условии, что он помещается на одном экране) и легко определить стоящую за ним логику.

Сопоставление шаблонов FTW!

Я предпочитаю использовать сопоставление шаблонов для решения этой проблемы. Мы можем взять нашу таблицу (таблицы) решений и напрямую сопоставить их с кодом таким образом, чтобы они выглядели и ощущались очень похожими на исходную информацию.

Возьмем приведенные выше таблицы и проиллюстрируем их в качестве примера. Я собираюсь использовать язык Rust, потому что в нем есть отличная система типов и встроенная функция сопоставления с образцом. Большинство языков сейчас поддерживают такой синтаксис (я не думаю, что JavaScript поддерживает… 🤨).

Форматирование пробельных символов я выбрал для того, чтобы проиллюстрировать, насколько тесно связаны эти два понятия, и облегчить чтение таблицы, хотя это личное предпочтение.

Если вы используете язык с хорошей системой типов и компилятором, то дополнительное преимущество использования сопоставления по образцу заключается в том, что вы получаете проверку вашей логики во время компиляции. В отличие от серии операторов if, вы будете предупреждены, если один из ваших шаблонов (строки таблицы) недостижим или если вы пропустили какие-либо случаи. В C# вы получите предупреждение компилятора с красивой подсказкой о том, какие случаи вы пропустили. Нередко в конце включается промежуточный случай, где вы можете решить, что делать — возможно, выдать ошибку.

Вот, собственно, и все! Дайте мне знать в комментариях, что вы думаете об этом патерне, использовали ли вы его раньше? Стали бы вы его использовать? Есть ли другие решения, которые вы нашли, которые работают лучше?

Оцените статью
devanswers.ru
Добавить комментарий