2011-09-08 11 views
5

कमांड ऑब्जेक्ट पैटर्न एक है कि मैं अभी भी वास्तव में समझने में सक्षम नहीं हूं और मुझे उस कोड में एक कार्यान्वयन मिला है जिसे मैं वर्तमान में काम कर रहा हूं, इसलिए मैंने इसे लंबे समय तक और कठिन अध्ययन किया ताकि मैं इसे अंत में प्राप्त कर सकूं असली दुनिया उदाहरण। समस्या यह है कि मुझे यकीन है कि यह उचित रूप से कार्यान्वित नहीं किया गया है और यह केवल किसी ऐसे व्यक्ति द्वारा किया गया है जो इसके बारे में पढ़ता है और सोचा कि यह यहां समझ में आया है।कमांड ऑब्जेक्ट पैटर्न wannabe या असली चीज़?

मुझे यह आप पर दिखाने की अनुमति दें (गोपनीयता संबंधी कारणों यह बहुत सरल बनाया जाएगा के लिए, लेकिन मैं मुख्य अवधारणाओं को दिखाने के लिए मेरी पूरी कोशिश करेंगे):

public class CommandOne 
{ 
    public CommandOne(Manager manager, MyForm form) 
    { 
     m_manager = manager; 
     m_form = form; 
    } 

    public void Execute() 
    { 
     m_manager.CommandOne(m_form); 
    } 
} 

public class CommandTwo 
{ 
    public CommandTwo(Manager manager, MyForm form) 
    { 
     m_manager = manager; 
     m_form = form; 
    } 

    public void Execute() 
    { 
     m_manager.CommandTwo(m_form); 
    } 
} 

पहली बात यह है कि मुझे अजीब के रूप में हमलों है कि ये दो वर्ग किसी भी अमूर्त वर्ग से विरासत में नहीं हैं और न ही एक आम इंटरफ़ेस को कार्यान्वित कर रहे हैं।

कोड इन आदेशों का उपयोग करता है इस प्रकार है:

public class MyForm : System.Windows.Forms.Form 
{ 
    public MyForm(Manager manager) 
    { 
     m_manager = manager; 
    } 

    private void SomeMethod() 
    { 
     .... 
     var cmd = new CommandOne(manager, this); 
     cmd.Execute(); 
     ... 
    } 

    private void OtherMethod() 
    { 
     .... 
     var cmd = new CommandTwo(manager, this); 
     cmd.Execute(); 
     ... 
    } 
} 

तो जिस तरह से मैं इसे देख, इस फार्म बिल्कुल प्रबंधक जो अपने कंस्ट्रक्टर्स के माध्यम से इसे करने के लिए इंजेक्शन की जा रही है को छोड़कर शामिल सभी वर्गों के लिए युग्मित है । तो इस कोड के साथ मुझे वास्तव में "कमांड" कक्षाएं बनाने का कोई लाभ नहीं दिखता है जो मूल रूप से प्रबंधक के तरीकों पर कॉल का प्रतिनिधित्व कर रहे हैं क्योंकि फॉर्म उन्हें तत्काल लागू कर रहा है और बाद में निष्पादन विधि को कॉल कर रहा है।

तो क्या कोई कृपया बता सकता है कि कौन से टुकड़े, यदि कोई हैं, तो यह कार्यान्वयन वास्तव में एक कमांड ऑब्जेक्ट पैटर्न होने के लिए गायब है और हालांकि यह बहुत ही व्यक्तिपरक हो सकता है, इस मामले में इसे लागू करने का क्या फायदा होगा?

धन्यवाद।

+0

'फॉर्म' के लिए उपयोग करने वाले आदेश क्या हैं? – SwDevMan81

+0

यह प्रबंधक में प्रतिनिधि विधि को भेजा जा रहा है जो उपयोगकर्ता से पूछने वाले संदेश बॉक्स को प्रदर्शित करता है यदि वह अपने परिवर्तनों को सहेजना चाहता है या नहीं, और उसके अनुसार फॉर्म की गुणों को संशोधित करता है। आईएमओ यह वास्तव में खराब डिजाइन है, लेकिन मुझे लगता है कि, सवाल के दायरे से परे :) –

उत्तर

9

जो आप यहां दिखा रहे हैं उसके आधार पर ऐसा लगता है कि कमांड पैटर्न का लाभ खो गया है। WinForms ऐप के संदर्भ में कमांड पैटर्न का उपयोग करने के कुछ कारण हैं।

आप एक कमांड निष्पादित करने के लिए बाद में

public interface ICommand 
{ 
    void Execute(); 
} 

निष्पादित आदेशों का एक इतिहास रखें ताकि वे उपयोगकर्ता द्वारा पूर्ववत किया जा सकता

public interface ICommand 
{ 
    void Execute(); 

    void Undo(); 
} 

चेक अनुमतियाँ वर्तमान उपयोगकर्ता के अधिकार हैं आप देखना चाहते हैं आदेश निष्पादित करें। उदाहरण के लिए, हो सकता है कि आपके पास RefundCustomerCommand हो और सभी ग्राहक सेवा एजेंटों को धनवापसी जारी करने का अधिकार न हो ताकि आप फ़ॉर्म पर एक बटन अक्षम करना चाहें।

public interface ICommand 
{ 
    void Execute(); 

    bool CanExecute { get; } 
} 

आप एक से अधिक आदेशों एक साथ रोल कर सकते हैं इस तरह एक समग्र में:

public class CompositeCommand : ICommand 
{ 
    private readonly List<ICommand> commands; 

    public CompositeCommand() 
    { 
     commands = new List<ICommand>(); 
    } 

    public void Add(ICommand command) 
    { 
     commands.Add(command); 
    } 

    public void Execute() 
    { 
     foreach (var command in commands) command.Execute(); 
    } 
} 

आदेश पैटर्न भी डेकोरेटर के साथ अच्छी तरह से काम करता है। आप आसानी से अपने आदेशों में अतिरिक्त क्रॉस-कटिंग व्यवहार जोड़ सकते हैं जैसे कि पुनः प्रयास करें:

public class RetryOnTimeout : ICommand 
{ 
    private readonly ICommand command; 
    private int numberOfRetries; 

    public RetryOnTimeout(ICommand command, int numberOfRetries) 
    { 
     this.command = command; 
     this.numberOfRetries = numberOfRetries; 
    } 

    public void Execute() 
    { 
     try 
     { 
      command.Execute(); 
     } 
     catch (TimeoutException) 
     { 
      if (++numberOfRetries > 3) 
       throw; 

      Execute(); 
     } 
    } 
} 
+0

धन्यवाद माइकल।तो आपके उत्तर से, क्या यह समझ में आता है कि फॉर्म अभी भी प्रबंधक को तुरंत चालू करेगा (मैनेजर पर अब निर्भरता इंजेक्शन के बारे में भूल जाओ) इसे किसी इंजेक्शन में, सभी आवश्यक आदेशों को किसी प्रकार के समग्र में बनाएं और उसके बाद ऑपरेशन के आधार पर आवश्यक कमांड को उचित इंटरफ़ेस को अपने इंटरफ़ेस को वापस करने के लिए आवश्यक है ताकि फ़ॉर्म केवल इसकी निष्पादन विधि चला सके? और दूसरा सवाल हालांकि यह व्यक्तिपरक हो सकता है, क्या यह सब समझ में आता है या यह अधिक है? क्या एक और पैटर्न का उपयोग करना बेहतर होगा? –

+0

मैं वास्तव में आपके परिदृश्य का पालन नहीं कर रहा हूं। यदि आपका समाधान जटिल है, उम्मीद है कि यह समस्या जटिल है। उचित आदेश खोजने और इंटरफ़ेस लौटने का विचार काफी आम है। उदाहरण के लिए, एसएमटीपी जैसे प्रोटोकॉल को लागू करने के लिए एक आम समाधान एक ऑब्जेक्ट होना है जो सॉकेट का प्रबंधन करता है और फिर संदेश (हेल्कोमांड, मेलफ्रोम कॉमांड, आरसीपीटीओ कॉमांड, इत्यादि ...) के आधार पर ऑब्जेक्ट कमांड को प्रेषित करता है। कमांड ऑब्जेक्ट्स को गतिशील रूप से देखा जा सकता है। –

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