2010-11-15 21 views
5

मेरे पास कक्षाओं का एक समूह है, जिनमें से प्रत्येक को कुछ बिंदुओं पर निर्णय लेने की आवश्यकता है, जिसमें दो या तीन दृष्टिकोणों को आंतरिक रूप से समान कार्यक्षमता को लागू करने के लिए आंतरिक रूप से उपयोग करना चाहिए। आदर्श रूप में, इसमें फ़ॉलबैक कार्यक्षमता शामिल होनी चाहिए, जहां यदि दृष्टिकोण विफल हो जाता है, तो यह दृष्टिकोण दृष्टिकोण (और शायद सी, डी, आदि तक पहुंचने के लिए) होता है। अब तक, मैं सिर्फ if (!success) { ApproachB code } जैसे कोडिंग का उपयोग कर रहा हूं। इसके साथ समस्या यह है कि कई बाद के तरीकों को भी पता होना चाहिए कि किस दृष्टिकोण को चुना गया था और उनमें से सभी अपने if (MethodChosen) { } else { } कथन भी विकसित करते हैं। मैं वास्तव में कुछ कम अनावश्यकता के साथ इस मुद्दे को हल करना चाहता हूं ... मैंने जो भी अन्य विकल्पों को माना है, उन्हें छोड़कर "वाइल्ड" लगता है। यहाँ तीन दृष्टिकोण मैं के बारे में सोचा हैं:"फॉलबैक" कक्षाओं को कार्यान्वित करना

  1. एक स्थिर .Create तरीका है जिसके दो व्युत्पन्न वर्ग की, बनाने के लिए जहां दो वर्गों एक अंतरफलक उन्हें समर्थन है फैसला करता है कि लागू करें। इसका नुकसान यह है कि आप दो बार एक ही कोड लिख रहे हैं, और यह वास्तव में "फॉलबैक" नहीं बना रहा है क्योंकि यह सभी निर्णय लेने में आगे बढ़ने के लिए मजबूर करता है। विधि विधि। यह 9/10 बार काम करना चाहिए, लेकिन अन्य 1/10 बार होंगे जहां मैं फॉलबैक केवल तभी ला सकता हूं जब प्राथमिक ने कोशिश की और असफल हो।
  2. उपरोक्त जैसा ही है, लेकिन आधार या अमूर्त वर्ग के साथ, या तो दोनों के लिए बैकिंग क्लास के रूप में, या फॉलबैक के लिए प्राथमिक श्रेणी के रूप में प्राथमिक के साथ। यह वही फॉलबैक नुकसान है, लेकिन कम से कम कम या कोई दोहराया कोड नहीं है। अर्थात

    public void SomeMethodOrConstructor() 
    { 
        if (someConditions) 
         MyChild = ChildClassA; 
        else 
         MyChild = ChildClassB; 
    } 
    
    
    public void Execute() 
    { 
        MyChild.Execute(); 
    } 
    

जब जरूरत विकल्प 3 दोनों के बीच डेटा गुजर रहा है के साथ समस्या:

  • बच्चे वर्गों के साथ एक सामान्य रूप से निर्मित सार वर्ग जो रन-टाइम में बदला जा सकता है को लागू करें। चूंकि इनमें से कुछ विधियां बाहरी वस्तुओं को मॉडलिंग कर रही हैं, जो काफी बार होगी। घोंसला वाले वर्ग स्वचालित रूप से अपने मूल वर्ग के साथ डेटा साझा करते हैं? या क्या मुझे इसे हर कॉल के साथ पास करना होगा?

    मुझे और कुछ और विचार करना चाहिए?


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

    अंतिम समाधान के साथ मदद करने वाले हर किसी के लिए धन्यवाद!

    उत्सुक के लिए, मेरे परम समाधान मोटे तौर पर इस तरह से काम किया:

    • हैंडलर सार कक्षा बनाएं, काफी विकिपीडिया लेख में बताया गया है, लेकिन एक public abstract Handler GetHandler() समारोह के साथ, और लोड की तरह अन्य अमूर्त विधियां जोड़ने, सहेजें, आदि
    • अभिभावक वर्ग के लिए निजी हैंडलर उप-वर्गों को कार्यान्वित करें (वे उप-वर्ग भी हो सकते हैं, क्योंकि वे केवल उस विशेष वर्ग के लिए चीजों को संभालेंगे ... बाद में नामकरण मुद्दों से बचाता है)। बच्चे वर्ग सभी अपने कन्स्ट्रक्टर में पैरेंट ऑब्जेक्ट के प्रकार का पैरामीटर लेते हैं, इसलिए उनके माता-पिता के डेटा तक आसानी से पहुंच होती है।
    • माता पिता वर्ग के निर्माता से, सेटअप जिम्मेदारी संचालकों की चेन/उत्तराधिकारियों (फिर से, सिर्फ उदाहरण की तरह), तो FirstHandler.GetHandler(this) फोन और परिणाम की दुकान तो वर्ग तो जो हैंडलर भविष्य में उपयोग करना जानता है।
    • अधिकतर प्रबंधित विधियां तो Handler.MethodName() पर आसानी से कम हो जाती हैं।
  • +2

    आप कोड को _eight_ रिक्त स्थान के साथ इंडेंट करके क्रमांकित सूची में डाल सकते हैं। – SLaks

    +0

    फ़ॉर्मेटिंग टिप के लिए धन्यवाद, जो मुझे दीवार चला रहा था! – RobinHood70

    उत्तर

    5

    Chain of Responsibility का उपयोग करें।

    श्रृंखला के- जिम्मेदारी पैटर्न एक डिजाइन आदेश वस्तुओं का एक स्रोत और प्रसंस्करण वस्तुओं की एक श्रृंखला से मिलकर पैटर्न है। प्रत्येक प्रसंस्करण वस्तु तर्क का एक सेट है कि आदेश वस्तुओं है कि यह संभाल कर सकते हैं, और के प्रकार उन है कि यह श्रृंखला में अगले प्रसंस्करण वस्तु को संभाल सकते हैं पास करने का तरीका बताता शामिल हैं। इस श्रृंखला के अंत तक नई प्रसंस्करण वस्तुओं को जोड़ने के लिए तंत्र भी मौजूद है।

    यह आपको पूरी तरह से करने की आवश्यकता के साथ फिट बैठता है।

    +0

    मैं आज दोपहर इसके साथ खेलूँगा, लेकिन मुझे पूरा यकीन है कि यह वह जवाब है जिसे मैं ढूंढ रहा था! – RobinHood70

    +0

    कुछ भी, बस मुझे एक चिल्लाओ। – Aliostad

    +0

    बाद की कॉल के संदर्भ में इसे कैसे कार्यान्वित किया जाए इस पर कोई सुझाव? मेरा विशिष्ट मामला अधिक सामान्य उदाहरण में डालने के लिए, मान लें कि मेरे पास लोड और सेव विधियां हैं, जहां लोड एक्सएमएल या टीXT फाइलों को संभालती है। सहेजें को "इसे फिर से समझने" की आवश्यकता नहीं है, लोड पहले ही निर्धारित कर चुका है कि यह क्या है। मैं सोच रहा हूं कि अभिभावक वर्ग को केवल एक हैंडलर संपत्ति की आवश्यकता है जो इंगित करता है कि आखिरकार कौन सा हैंडलर घटना को संभाला, लेकिन मुझे यकीन नहीं है कि इसे कैसे कार्यान्वित किया जाए। – RobinHood70

    0

    मैं तुम्हें Task/Task<T>, जरूरत है विशेष रूप से ContinueWith(Action<Task>) विधि और 4 गुण: IsCanceled, IsCompleted, IsFaulted और Result

    1

    मैं शायद यहां रणनीति पैटर्न का उपयोग करूंगा।

    http://en.wikipedia.org/wiki/Strategy_pattern

    आप केवल पूरे वर्गों के बजाय delgates पारित करने के लिए की जरूरत है। यदि सभी विधियां प्रसंस्करण के लिए समान जानकारी का उपयोग करती हैं, तो यह सहायक हो सकती है।

    +0

    यह भी एक अच्छा समाधान है, हालांकि अगर मैं सही ढंग से समझ रहा हूं, तो मेरे पास जिस संभावित व्यवहार की तलाश है, उसके पास यह नहीं होगा। – RobinHood70

    +0

    ऐसा लगता है कि आपकी रणनीति पैटर्न सभी के बाद खेल में आ रही है। :) धन्यवाद! – RobinHood70

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