Использование F# для создания хорошо отлаживаемого движка бизнес-правил

Эта проблема

У меня есть код в F#, представляющий логическое дерево. Это механизм бизнес-правил с некоторыми довольно простыми математическими функциями. Я хотел бы иметь возможность запускать правила дерева много раз и видеть, сколько раз проходит каждый конкретный маршрут через дерево.

Требования состоят в том, чтобы базовые правила не менялись слишком сильно по сравнению с простыми операторами соответствия, которые я использую в данный момент. Было бы хорошо пометить важные функции атрибутом, но добавить вызов функции регистрации в каждом узле - нет. Я хочу иметь возможность запускать код в двух режимах: высокопроизводительный стандартный режим, который просто дает ответы, а затем "исследовательский режим", который дает больше деталей за каждым вызовом. Хотя я не против сложного кода для динамической загрузки и профилирования правил, сам код правил должен выглядеть просто. В идеале я не хотел бы полагаться на сторонние библиотеки - powerpack в порядке. Решение также должно быть нацелено на среду выполнения.NET 4.0.

Потенциальные решения

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

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

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

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

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

type ProductType = | ProductA | ProductB

let costOfA quantity =
    100.0 * quantity

let costOfB quantity =
    if quantity < 100.0 then
        20.0 * quantity
    else
        15.0 * quantity

let calculateCostOfProduct productType quantity =
    match productType with
    | ProductA -> costOfA quantity
    | ProductB -> costOfB quantity

0 ответов

Другие вопросы по тегам