Архитектура для обработки как отмены, так и уведомлений

В настоящее время я разрабатываю сложный веб-сайт, который должен поддерживать отмену и уведомления для операций CRUD.

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

Под Уведомлениями я подразумеваю, что при создании/изменении/удалении элемента другие пользователи, заинтересованные в этом элементе, получат уведомление на сайте (при следующей загрузке новой страницы) и будут также получать уведомления по электронной почте или SMS, если они просили об этом.

Реализовать любую функцию очень просто: отмена включает в себя сохранение информации об отмене (в основном старая версия измененных или удаленных элементов), в то время как уведомления так же просты, как вставка объекта уведомления в соответствующие таблицы и отправка электронной почты/SMS на лету.

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

Каких шаблонов, рекомендаций или ошибок следует избегать при создании такой системы?


person Victor Nicollet    schedule 13.01.2011    source источник


Ответы (2)


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

РЕДАКТИРОВАТЬ1: Переосмыслив это, я бы, наверное, сразу же продолжил. В противном случае у вас возникнет проблема с окончанием сеанса пользователя до истечения времени ожидания.

РЕДАКТИРОВАТЬ 2. Другой вариант — использовать Windows Workflow Foundation 4 (WF4) и компенсацию. Настройте долговременный постоянный рабочий процесс в качестве службы WCF. Рабочий процесс может быть просто действием WCF Receive для его запуска, действием Delay и пользовательским действием для отправки уведомлений; вам может даже не понадобиться CompensableActivity (если задержка не истекла и уведомление не было отправлено, отменять нечего). Каждый запрос уведомления делает вызов WCF для запуска нового экземпляра рабочего процесса. Если пользователь отменяет, прервите экземпляр. (Может быть проще выполнить действие Pick с задержкой и другим действием WCF Receive, которое отменяет уведомление при вызове.) Предостережение: я не реализовал подобную систему.

person TrueWill    schedule 13.01.2011
comment
Это действительно то, как я бы справился с вещами независимо. Я ищу конкретный шаблон, который позволяет мне делать и то, и другое одновременно. - person Victor Nicollet; 18.01.2011
comment
В зависимости от требований пользователя либо уведомления должны быть с возможностью отмены, либо наоборот. Хотя поддержка SRP — это хорошо, я скорее пожертвую SRP, чем пожертвую пользовательским интерфейсом. Думаю, я прошу способ сделать это, повредив SRP как можно меньше. - person Victor Nicollet; 19.01.2011

Немного поэкспериментировав как с мыслью, так и с кодом, мне удалось выделить ряд принципов.

  • Пользователь может отменить операцию, нажав кнопку отмены, или выполнив обратную операцию (например, удалив свой комментарий). С точки зрения уведомлений нет причин рассматривать эти две ситуации по-разному.
  • Уведомления об одном и том же объекте, происходящие примерно в одно и то же время, должны быть по возможности сгруппированы вместе: нет смысла отображать «А прокомментировал ваш пост»… «Z прокомментировал ваш пост» вместо «А, B... и Z прокомментировали ваш пост". Таким образом, уведомления о создании и удалении должны быть сгруппированы вместе в соответствии с правилами группировки: если они расположены достаточно близко друг к другу, они отменяют друг друга.
  • Из-за возможности отмены никогда не отправляйте уведомления по электронной почте сразу. Вместо этого подождите две минуты. Если операция отменена, правила группы создания и удаления удалят неотправленное уведомление, пока оно все еще находится на рассмотрении. Конечно, если пользователь в настоящее время подключен, вы можете отображать уведомления в режиме реального времени, потому что, в отличие от электронной почты, уведомления в реальном времени могут быть «забраны».

Основываясь на этих принципах, я решил создать два отдельных уровня поверх уровня доступа к данным:

  • Набор семантически значимых операций, таких как "опубликовать новый комментарий" или "удалить комментарий", которые затем подключаются для отправки уведомлений.
  • Определение пары операций включена/отмена : аспект "отмены" в "публикации нового комментария" означает "удаление комментария".

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

И наоборот, средства «отмены» просто вызывают код из семантического уровня, не требуя каких-либо сведений об отправляемых уведомлениях.

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

person Victor Nicollet    schedule 23.02.2011