подходит ли конечный автомат для обработки изменений состояния в системе стимулирования сбыта? - PullRequest
2 голосов
/ 23 марта 2009

Я занимаюсь разработкой системы стимулирования сбыта, и я только что натолкнулся на что-то, что, вероятно, могло бы быть обработано с помощью шаблона конечного автомата, но у меня пока нет опыта работы с конечными автоматами. Может быть, конечный автомат совершенно бесполезен в этой ситуации :) Таким образом, у меня есть рекламная акция, которая имеет определенную продолжительность, несколько назначенных клиентов, продукты, скидки и т. Д. Каждая акция также имеет свое состояние. Там около 5 штатов. Переходы между состояниями строго определены - невозможно напрямую изменить состояние 1 на состояние 3 - пользователь должен сначала изменить состояние на 2. Есть некоторые ограничения, такие как «невозможно добавить больше продуктов, когда продвижение в состоянии 3-5». Или ограничения типа «только суперпользователи могут редактировать затраты на продвижение, когда они находятся в состоянии 3-5».

Я только что прочитал о http://www.codeplex.com/SimpleStateMachine, но я не уверен, что это не слишком сложно для этого случая. Я мог бы обрабатывать логику состояния на своем сервисном уровне, используя такие вещи, как:

if (promotion.state == statesRepository.GetState3() && false == loggedUser.IsInRole("superUser")){
   throw new PromotionStateException("user not allowed to edit promotion in this status");
}
...

или

public void ChangePromotionStatus(promotion, newStatus){
  if (promotion.Status == status1 && newStatus != statesRepo.GetState2()){
    throw new StateTransitionException("unable to change from status 1 to " + newStatus);
  }
}

Но мне не нравится этот вид кода - должен быть какой-то лучший подход :) У кого-нибудь есть совет? Конечно, я мог бы разделить заботы и разработать такие службы, как PromotionStatusChangeReviewService, PromotionEditPermissionService и т. Д., Чтобы сделать код менее связанным, но, возможно, есть какое-то лучшее решение, которого я сейчас не вижу.

Ответы [ 2 ]

4 голосов
/ 23 марта 2009

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

  • Конечные автоматы не помогают, если вы не можете маркировать состояния осмысленным образом. «статус 3» ничего не значит; вам нужно назвать это чем-то полезным, например, «Продвинутый», «Активный», «Завершенный» и т. д.

  • Часть шаблона конечного автомата предполагает, что у вас есть отдельная сущность, которая понимает состояния и способы перехода между ними. Например, в вашем примере не должно быть метода, подобного ChangePromotionStatus(), где он взрывается, если состояние не должно быть разрешено. Конечный автомат должен просто предотвращать переходы, которые не могут произойти.

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

2 голосов
/ 27 марта 2009

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

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

Однако, если это действительно так, что ваши состояния полностью последовательны - то есть они всегда идут abcde или назад и продвигаются ровно на один шаг, я не уверен, что конечный автомат имеет смысл, потому что есть для выбора следующего состояния не требуется никакого специального контекста - вы можете идти только назад или вперед, поэтому достаточно упорядоченного списка состояний (например, Enum) в сочетании с логикой Next / Previous - но процессы реального мира редко бывают настолько строго линейными, даже хотя они могут показаться на первый взгляд.

...