2011-05-04 7 views
5

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

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

तो, कल्पना निम्नलिखित (बहुत सरल) वर्ग:

class Acquisition 
{ 
    public Int32 IntegrationTime { get; set; } 
    public Double Battery { get; set; } 
    public Double Signal { get; set; } 
} 

interface IAnalogOutputter 
{ 
    double getVoltage(Acquisition acq); 
} 

class BatteryAnalogOutputter : IAnalogOutputter 
{ 
    double getVoltage(Acquisition acq) 
    { 
     return acq.Battery; 
    } 
} 

अब, हर ठोस रणनीति वर्ग मेरी अधिग्रहण वर्ग है, जो भी सबसे अधिक संभावना वर्गों में से एक के बाद से संशोधित किया जा रहा है के लिए युग्मित किया जाना है यह हमारे आवेदन के लिए मूल है। यह अभी भी पुराने डिजाइन पर एक सुधार है, जो Acquisition कक्षा के अंदर एक विशाल स्विच स्टेटमेंट था। प्रत्येक प्रकार के डेटा में एक अलग रूपांतरण विधि हो सकती है (जबकि बैटरी एक साधारण पास-थ्रू है, जबकि अन्य सभी सरल नहीं हैं), इसलिए मुझे लगता है कि रणनीति पैटर्न या इसी तरह का रास्ता होना चाहिए।

मैं यह भी ध्यान दूंगा कि अंतिम कार्यान्वयन में, IAnalogOutputter एक इंटरफेस के बजाय एक अमूर्त वर्ग होगा। ये कक्षाएं ऐसी सूची में होंगी जो उपयोगकर्ता द्वारा कॉन्फ़िगर करने योग्य है और एक XML फ़ाइल को क्रमबद्ध किया गया है। सूची रनटाइम पर संपादन योग्य होनी चाहिए और याद किया जाना चाहिए, इसलिए Serializable हमारे अंतिम समाधान का हिस्सा होना चाहिए। अगर यह एक फर्क पड़ता है।

मैं कैसे सुनिश्चित कर सकता हूं कि प्रत्येक कार्यान्वयन वर्ग को मेरे सबसे महत्वपूर्ण वर्गों में से किसी एक को टाई बिना काम करने के लिए आवश्यक डेटा मिल जाए? या क्या मैं पूरी तरह से गलत तरीके से इस तरह की समस्या का सामना कर रहा हूं?

उत्तर

0

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

interface IOutputValueProvider 
{ 
    Double GetBattery(); 
    Double GetSignal(); 
    Int32 GetIntegrationTime(); 
    Double GetDictionaryValue(String key); 
} 

interface IAnalogOutputter 
{ 
    double getVoltage(IOutputValueProvider provider); 
} 

class BatteryAnalogOutputter : IAnalogOutputter 
{ 
    double getVoltage(IOutputValueProvider provider) 
    { 
     return provider.GetBattery(); 
    } 
} 

class DictionaryValueOutputter : IAnalogOutputter 
{ 
    public String DictionaryKey { get; set; } 
    public double getVoltage(IOutputValueProvider provider) 
    { 
     return provider.GetDictionaryValue(DictionaryKey); 
    } 
} 

तो फिर, मैं सिर्फ यह सुनिश्चित करने के Acquisition इंटरफ़ेस लागू करता है की जरूरत है:

class Acquisition : IOutputValueProvider 
{ 
    public Int32 IntegrationTime { get; set; } 
    public Double Battery { get; set; } 
    public Double Signal { get; set; } 
    public Dictionary<String, Double> DictionaryValues; 

    public double GetBattery() { return Battery;} 
    public double GetSignal() { return Signal; } 
    public int GetIntegrationTime() { return IntegrationTime; } 
    public double GetDictionaryValue(String key) 
    { 
     Double d = 0.0; 
     return DictionaryValues.TryGetValue(key, out d) ? d : 0.0; 
    } 
} 

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

2

Strategy Pattern एक - आमतौर पर जटिल - संचालन/गणना encapsulates।

वोल्टेज वापस करना चाहते विन्यास की

  • टुकड़े
  • अधिग्रहण डेटा के कुछ पर निर्भर है

तो मैं किसी अन्य वर्ग में इन डाल दिया और करने के लिए इसे पारित होगा रणनीति कार्यान्वयनकर्ताओं।

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


अद्यतन

ठीक है, ऐसा लगता है कि अपने कार्यान्वयन अधिग्रहण डेटा का केवल एक टुकड़ा की जरूरत है। यह एक रणनीति पैटर्न के लिए थोड़ा असामान्य है - लेकिन मुझे विश्वास नहीं है कि यह Visitor बेहतर है इसलिए रणनीति ठीक है। मैं एक वर्ग बनाउंगा जिसमें प्रॉपर्टी, अधिग्रहण डेटा (शायद इससे विरासत में) कॉन्फ़िगरेशन के अतिरिक्त कॉन्फ़िगरेशन के अतिरिक्त होगा।

+0

स्पष्टीकरण के लिए - अधिग्रहण डेटा में जानकारी के लगभग 20 टुकड़े होते हैं, जिनमें से सभी का उपयोग विभिन्न वोल्टेज आउटपुट द्वारा किया जाएगा। प्रत्येक कार्यान्वयन केवल डेटा के एक टुकड़े का उपयोग करेगा, लेकिन वोल्टेज आउटपुटर के विभिन्न संभावित कार्यान्वयन के समान संख्या (20) होगी। तो मैं 'अधिग्रहण' से "दूसरी कक्षा [इसे] रणनीति कार्यान्वयनकर्ताओं को पास करने के लिए कैसे प्राप्त करूं?" हालांकि क्रमबद्धता के बारे में अच्छा बिंदु, मैं निश्चित रूप से उस पर विचार करूंगा। – drharris

0

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

public class OutputterFactory 
{ 
    public static IAnalogOutputter CreateBatteryAnalogOutputter(Acquisition acq) 
    { 
     return new BatteryANalogOutputter(acq.Battery); 
    } 



} 
+0

मैंने इस बारे में सोचा था, लेकिन फिर यह डेटा के प्रत्येक नए टुकड़े के लिए लगता है, मुझे एक संपत्ति, एक विधि, और एक वर्ग जोड़ना है। हालांकि यह थोड़ा और कम कर देता है, यह 3 की शक्ति से क्रूर वृद्धि की मात्रा बनाता है। लेकिन, अब मैं सोच रहा हूं कि इसके लिए अलग-अलग तरीकों का उपयोग करना सबसे अच्छा विकल्प होगा। – drharris

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