Как теоретически работает система правил, подобная той, что используется в Outlook Express?Как это можно было сделать?

StackOverflow https://stackoverflow.com/questions/2043546

  •  19-09-2019
  •  | 
  •  

Вопрос

Мне это любопытно:

В Microsoft Outlook Express (или Outlook, плохо помню, я пользователь Mac) есть что-то действительно классное.Общие правила:

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

Эти правила выглядели примерно так:

"Если тема письма во входящих содержит "foo", или"bar", или "foobar", удалите его"

Мне нужно закодировать что-то подобное для мощной системы проверки формы.Разработчик должен просто иметь возможность создавать подобные правила:

rule: [password_1] is_not_equal_with [password_2]
consequence: show_error '2921'

rule: [firstName] has_less_characters_than '2'
consequence: show_error '1211'

rule: [age] is_numeric, is_smaller_than '13', is_greater_than '130'
consequence: show_error '1522'

rule: [gender] is_equal_with 'female'
consequence: show_group [female_questions]

rule: [termsAndConditionsAccepted] is_not_checked
consequence: show_error '482'

rule: [age] is_less_than 21
consequence: hide_group [income_questions]

Что ж, у меня есть несколько идей, как это можно было бы сделать, и я опубликую их здесь в качестве ответа.Но прежде чем я изобрету велосипед заново:Существуют ли какие-либо письменные концепции, которые я могу использовать в качестве основы для разработки основанной на правилах системы проверки, подобной этой?Или, если нет, есть ли у вас какие-либо предложения, как это можно было бы сделать?

В приведенном выше примере все, что заключено в квадратные скобки, является именем элемента html-формы.Все в апостроф" - это "жестко закодированное" значение для сравнения.

Определенные правила переводятся в PHP-код И JavaScript-код для выполнения проверки как на стороне клиента, так и на стороне сервера.

Функции, на которые это должно быть способно:

  • Условные правила:Что-то A зависит от чего-то B
  • Сравнение значений:Для целых чисел, чисел с плавающей запятой, строк
  • Включите также некоторую логику управления формой, как в примере "[gender] is_equal_with 'female'" выше.

Как это можно было сделать?Какие сущности я должен рассмотреть с научной точки зрения?

Я думаю, что теоретическая концепция этого не зависит от платформы.Хотя я реализую это на PHP и JavaScript, нет причин, по которым разработчик C ++ не должен отвечать ;-) (Кстати, я сторонник Objective-C)

Это было полезно?

Решение

Возможно, вы захотите ознакомиться с некоторыми движками правил с открытым исходным кодом;или даже оплаченный.

Примеры включают
Заплати за это:
Руководить, Механизм разработки бизнес-правил, Механизм Разработки бизнес-правил ASA

Открытый исходный код:
Открытые правила, Пускает слюни

Их гораздо больше.Включая некоторые встроенные в java (Java Rule Engine API (JSR94)) и .Net (Windows Workflow Foundation Rules Engine).

Хотя не уверен насчет прямого PHP.

В качестве дополнительного примечания, я использовал пару движков, таких как Правила Хейли (до того, как они были куплены Oracle) для управления веб-интерфейсами.Имейте в виду, что скорость выполнения абсолютно важна.У нас был Хейли, обрабатывающий около 2000 правил за загрузку страницы (приложение для ипотеки), и он выполнялся менее чем за 40 мс (это не опечатка).Мы использовали его, чтобы определить, какие поля были на странице, а также определить, соответствовали ли введенные данные юридическим стандартам и даже были ли они введены правильно.

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

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

Это также было эффективно в меньшем масштабе, но я ограничил это только простыми ответами "идти / не идти".

Другие советы

Для небольшого количества правил и сообщений вы можете применить алгоритм грубой силы:возьмите каждое правило и каждое сообщение и сравните, подходят ли они друг другу.Вы попадете в O (rm) сложность, где r - количество правил, а m - количество сообщений, не принимая во внимание, что правило может иметь несколько условий.

Для огромного количества правил или сообщений вы можете реализовать сеть Rete (http://en.wikipedia.org/wiki/Rete_algorithm).Это требует некоторого объема памяти, но на практике выполняется намного быстрее.В зависимости от того, как вы разрабатываете свои правила, вы столкнетесь с различными сложностями.

Первый подход прост, и я не думаю, что мне нужно его объяснять.Однако, если вам понадобится помощь, дайте мне знать, и я подробно изложу эту идею.Позвольте мне объяснить второй подход:

Прочтите немного об алгоритме Rete, прежде чем идти дальше.

В альфа-части сети Rete вы будете хранить различные условия, которые указаны в ваших правилах.Некоторые правила могут иметь общие условия.Нравится:

Правило 1:ЕСЛИ (сообщение.дата равна 24.10.2009) И (заголовок сообщения содержит "привет") ТОГДА сделайте что-нибудь 1

Правило 2:ЕСЛИ (message.hasAttachement имеет значение TRUE) И (message.дата равна 24.10.2009) ТОГДА сделайте что-нибудь 2

Таким образом, альфа-часть сети будет состоять из 3 элементов

  • C1:(сообщение.дата равна 24.10.2009)
  • C2:(заголовок сообщения содержит "привет")
  • C3:(значение message.hasAttachement равно TRUE)

В сети бета-тестирования у вас будет два узла соединения, которые связывают C1-C2 и C3-C1.

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

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

Для получения дополнительной информации о Rete:

  • Производственное согласование для больших обучающих систем /--Роберт Б.Дооренбос.(1995)
  • Об эффективном внедрении производственных систем / Чарльз Л.Форги (1979)

В объектно-ориентированном проектировании одним из подходов является реализация шаблона команд или, для более сложных нужд, шаблона интерпретатора.Обычно вы создаете несколько классов для разных категорий правил, и вы можете создавать их для более сложных сценариев (например, создавая CompositeRule).;все они поддерживают интерфейс типа Execute() или Execute(контекст).

Вы создаете очередь экземпляров правила и вызываете Execute (контекст) для каждого из них для каждого объекта, с которым выполняется действие.Контекст будет содержать экземпляр объекта (сообщения, или формы, или чего-то еще), с которым вы действуете.

Объедините правила в цепочку цепочка ответственности.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top