2012-11-12 15 views
8

bbv.Common.StateMachine कक्षा मैंने कभी देखा है सबसे अच्छा राज्य मशीन कोड है। लेकिन इसमें केवल एक चीज नहीं है: वर्तमान स्थिति प्राप्त करना।bbv.Common.StateMachine (अब Appccelerate.StateMachine) कक्षा से वर्तमान स्थिति कैसे प्राप्त करें?

यह एक आदेश ट्रैकिंग प्रणाली है:

fsm = new ActiveStateMachine<States, Events>(); 

     fsm.In(States.OrderCreated) 
      .On(Events.Submitted) 
      .Goto(States.WaitingForApproval); 
     fsm.In(States.WaitingForApproval) 
      .On(Events.Reject) 
      .Goto(States.Rejected); 
     fsm.In(States.WaitingForApproval) 
      .On(Events.Approve) 
      .Goto(States.BeingProcessed); 
     fsm.In(States.BeingProcessed) 
      .On(Events.ProcessFinished) 
      .Goto(States.SentByMail); 
     fsm.In(States.SentByMail) 
      .On(Events.Deliver) 
      .Goto(States.Delivered); 

     fsm.Initialize(States.OrderCreated); 
     fsm.Start(); 
     fsm.Fire(Events.Submitted); 
     // Save this state to database 

आप देख सकते हैं कि यह कैसे आसानी से काम करता है।

लेकिन मैं डेटाबेस में ऑर्डर स्थिति को सहेजना चाहता हूं। इसलिए मैं यह दिखाने में सक्षम हूं कि कौन सा राज्य आदेश है।

मैं एक

fsm.GetCurrentState() 
//show this state in the a table 

विधि की जरूरत है। असल में एक तरीका है: मैं ExecuteOnEntry का उपयोग कर सकता हूं और प्रत्येक राज्य की प्रविष्टि पर स्थानीय मूल्य बदल सकता हूं। लेकिन प्रत्येक राज्य के लिए ExecuteOnEntry लिखना बोझिल होगा क्योंकि मैं खुद को दोहरा दूंगा!

ऐसा करने का एक नाजुक तरीका होना चाहिए।

+1

क्या करने के लिए आसान है आप जानते हैं कि bbv.Common का नाम बदलकर बदल दिया गया है। हमारा नया होमपेज देखें http://www.appccelerate.com –

उत्तर

13

के रूप में डैनियल बताया गया है, इस डिजाइन कर रहा है। मुझे समझाएं क्यों:

राज्य मशीन घटनाओं की कतार में अनुमति देता है। इसलिए, राज्य मशीन को अपने वर्तमान राज्य के बारे में पूछना भ्रामक हो सकता है। यह वर्तमान में राज्य ए में है, लेकिन पहले से ही एक घटना कतारबद्ध है जो इसे बी बी

इसके अलावा, मैं इसे राज्य मशीन आंतरिक राज्यों को जोड़ने के लिए खराब डिजाइन मानता हूं (जिन्हें आप अपने राज्य मशीन परिभाषा) सीधे राज्य मशीन बाहरी राज्यों (जिन्हें आप डेटाबेस में जारी रखना चाहते हैं) के साथ। यदि आप इन दोनों को सीधे जोड़ते हैं, तो आप बाहर की स्थिति को प्रभावित किए बिना आंतरिक रूप से राज्य मशीन को दोबारा करने की क्षमता खो देते हैं (आपके मामले में डेटाबेस में)। मुझे अक्सर उस परिदृश्य का सामना करना पड़ता है जिसमें मुझे ए 1 और ए 2 में एक राज्य ए को विभाजित करना होता है क्योंकि मुझे उन्हें अलग-अलग क्रियाएं संलग्न करनी पड़ती हैं, लेकिन फिर भी वे पर्यावरण के लिए एक ही राज्य का प्रतिनिधित्व करते हैं। इसलिए, मैं दृढ़ता से सलाह देता हूं कि आप आंतरिक और बाहरी राज्यों को अलग करें, या तो आपने OnEntryExecute() के साथ लिखा है या मैपिंग प्रदान करके और एक्सटेंशन का उपयोग करके।

public class CurrentStateExtension : ExtensionBase<State, Event> 
{ 
    public State CurrentState { get; private set; } 

    public override void SwitchedState(
     IStateMachineInformation<State, Event> stateMachine, 
     IState<State, Event> oldState, 
     IState<State, Event> newState) 
    { 
     this.CurrentState = newState.Id; 
    } 
} 

आप इस तरह से राज्य मशीन के लिए एक्सटेंशन जोड़ सकते हैं:

currentStateExtension = new CurrentStateExtension(); 
machine.AddExtension(currentStateExtension); 
बेशक

आप सीधे इस एक्सटेंशन का उपयोग कर सकते हैं पहुंच पाने के लिए यह एक विस्तार है कि आप वर्तमान स्थिति मिल जाएगा है वर्तमान स्थिति में भी। इसे और भी आसान बनाने के लिए, राज्य मशीन को परिभाषित करने वाली कक्षा को विस्तार लागू करें और स्वयं को एक एक्सटेंशन के रूप में पास करें।आपको अतिरिक्त कक्षा से छुटकारा पाने दें।

एक अंतिम ध्यान दें: जब आप bbv.Common के बारे में सवाल (या Appccelerate के रूप में यह अब कहा जाता है) गूगल समूह में https://groups.google.com/forum/?fromgroups#!forum/appccelerate में पूछते हैं, यह मेरे सवाल का जवाब खोजने के लिए और यह ;-)

+0

धन्यवाद, मैं इसे ASAP आज़माउंगा। –

4

यह डिज़ाइन द्वारा है। हम राज्य मशीन की स्थिति को डिजाइन गंध के रूप में पूछने पर विचार करते हैं। लेकिन निश्चित रूप से अपवाद के मामले हैं। आपके पास निम्नलिखित दो विकल्प हैं:

  1. आदेश की स्थिति को बचाने के लिए ExecuteOnEntry विधियों का उपयोग करें। यह जाने का तरीका दर्शाता है क्योंकि आप अपने व्यापार तर्क में राज्यमाचिन के राज्यों को रिसाव नहीं करना चाहते हैं।
  2. अपना खुद का राज्य मशीन सजावट लिखें जो आंतरिक रूप से StateMachine<TState, TEvent> का उपयोग करता है। यह राज्य का खुलासा करता है।

डैनियल

संबंधित मुद्दे