2009-03-23 5 views
2

저는 판촉 시스템을 개발 중이며 상태 머신 패턴으로 처리 될 수있는 무언가를 밟았지만 아직 상태 시스템에 대한 경험은 없습니다. 어쩌면 상태 머신은이 상황에서 전혀 쓸모가 없습니다 :) 그래서 일부 기간, 일부 할당 된 고객, 제품, 할인 등 판매 촉진을 가지고있다. 각 프로모션도 상태가있다. 대략 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 등과 같은 서비스를 개발하여 코드를 덜 결합 할 수는 있지만 지금은 볼 수없는 몇 가지 해결책이있을 것입니다.

답변

4

다섯 가지 상태는 상태 시스템에 너무 복잡하지는 않지만, 몇 가지 전환을 특수하게 또는 명시 적으로 처리하려고하면 몇 가지 문제가 발생한다고 생각합니다. 여기에 몇 가지 팁이 있습니다 :

  • 상태 머신은 의미있는 방법으로 상태에 레이블을 지정할 수 없다면 도움이되지 않습니다. "상태 3"은 아무것도 의미하지 않습니다. 당신은 "Promoted", "Active", "Completed"등과 같이 유용한 것으로 부를 필요가 있습니다.

  • 상태 시스템 패턴의 일부로 상태를 이해하고 분리 된 개체를 전환하는 방법을 알고 있다고 가정합니다. 예를 들어, ChangePromotionStatus()과 같은 메소드가 없어야합니다 (예 : 상태가 허용되지 않아야하는 경우). 상태 머신은 단순히 발생할 수없는 전환을 방지해야합니다.

  • 가능한 전환 수가 적고 잘 정의되어 있고 라벨을 지정하는 것이 의미가있는 경우 전환의 이름을 지정하는 것이 좋습니다. 이것은 전환이 모두 같은 일을하지만 약간 다른 방식으로 수행되는 경우 특히 유용합니다.

+0

단순화를 위해 상태 라벨을 숫자로 단순화했습니다. "제안", "확인 됨", "계획"등의 이름이 붙었습니다. "ChangePromotionStatus"응답 : 전환 로직을 배치해야한다고 생각합니다. 특정 클래스. 나는 그것을 모두 결합하는 방법을 알아낼 수 없다. SM에 대해 더 자세히 읽으십시오. – Buthrakaur

2

존이 머리에 못을 박았습니다. 상태 시스템을 사용하여 모델링 한 프로세스가 도메인 엔티티와 분리되어야합니다. 귀하의 도메인 엔티티는 특정 이벤트에 따라 상태에서 상태로 전환하는 작업을 관리하는 상태 시스템에서 사용 중이라는 직접적인 지식을 갖고 있지 않아야합니다. 그러나 은 각 상태의 비즈니스 의미를 이해합니다. 해당 주와 관련된 비즈니스 규칙을 시행하거나 적용 할 수 있습니다.

상태 시스템이 관리하는 데 적합한 도메인 엔티티는 상태 시스템의 상태로 작동하는 일종의 상태를 가지며 상태 시스템이 상태를 결정하는 데 사용할 수있는 이벤트를 발생시킵니다 이행이 적절하다.

그러나 실제로 상태가 인 경우 순차적입니다. 즉, 항상 abcde 또는 뒤로 이동하여 정확하게 한 단계 만 전달하면 상태가 의미있는 것이지 확실하지 않습니다. 특수한 상황이 없기 때문입니다. 다음 상태를 선택하는 데 필요한 - 앞으로 또는 앞으로 만 이동할 수 있으므로 다음/이전 논리와 결합 된 모든 상태 목록 (예 : 열거 형)으로 충분해야합니다. 그러나 현실 세계 프로세스는 거의 선형 적이 지 않습니다. 처음에는 붉어지는 것처럼 보입니다.