2011-02-10 20 views
5

मैं संभवतः का एक सेट है बयान है कि इस तरह दिखेगा यदि:कथन - डिजाइन पैटर्न अगर विशाल सरल?

if (a and b and c and d) { 
    // do stuff 
} else (!a and b and c and d) { 
    // do something else 
} else (!a and !b and c and D) { 
    // do yet something else 
} ... 

और इतने पर सभी संभव क्रमपरिवर्तन के लिए।

मैं ऐसा करने के बारे में सोचा:

switch ((a ? 'Y' : 'N') . (b ? 'Y' : 'N') . (c ? 'Y' : 'N') . (d ? 'Y' : 'N')) { 

    case 'YNYN': 
    // do stuff 
    break; 

    case 'NNNN': 
    // etc. 
    break; 

} 

वहाँ एक बेहतर तरीका है?

+4

कम-कथन का उपयोग करें। गंभीरता से, यह सवाल बहुत अस्पष्ट है –

+1

अच्छी तरह से स्विच का उपयोग न करें, कृपया। –

+2

मुझे नहीं लगता कि 'और' यहां काम करेगा (स्विच के अंदर)। '.' का प्रयोग करें? http: // codepad।संगठन/X4fIQsSz – Dogbert

उत्तर

0

मुझे लगता है कि आप निर्णय वृक्ष है, जहां विभिन्न नोड्स संभव अंत राज्य हैं के साथ इस समस्या को हल करने पर विचार करना चाहिए। तो आप अपनी समस्या को एक पेड़ में लिख सकते हैं, और इन सभी ifs से छुटकारा पा सकते हैं ....

0

मैंने आपके केस स्टेटमेंट के लिए एक समान दृष्टिकोण लिया जब मुझे शर्तों के एक सेट के आधार पर डेटा एकत्र करने की आवश्यकता थी, जिनमें से पांच स्विच थे जो चालू या बंद हो सकते थे।

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

0

हाँ, वहाँ एक बेहतर तरीका है।

ओह, तुम कि तुलना में अधिक विवरण चाहते थे? खैर, आपको चार चर के साथ कुछ प्रकार की सत्य तालिका दिखाई देती है। क्या 16 संभावित परिणाम (2^4) हैं, या आप केवल एक सबसेट में रूचि रखते हैं? यदि कोई वैरिएबल है जिसके परिणामस्वरूप लगभग समान संख्या में परिणाम हैं, तो संभवत: बयान के रूप में अपने शीर्ष के रूप में उपयोग करें, और नेस्टेड ifs का उपयोग करें।

if (b) { 
    // cases where b is true 
    if (...) 
    ... 
} else { 
    // cases where b is false 
    if (...) 
    ... 
} 

आप स्विच स्टेटमेंट का भी उपयोग कर सकते हैं, लेकिन वाई और एन का उपयोग स्ट्रिंग के बजाय बिटफील्ड का उपयोग कर सकते हैं।

7

क्या मैं संभावना (बारीकियों को जानने के बिना) करना होगा प्रत्येक राज्य के लिए कक्षाओं की एक श्रृंखला का निर्माण होता है। तब उस वर्ग पर doStuff धक्का:

class DoStuff { //The Client 
    protected $strategies = array(); 
    public function addStrategy(iDoStuffStrategy $strategy) { 
     $this->strategies[] = $strategy; 
    } 
    public function doStuff ($a, $b, $c, $d) { 
     foreach ($this->strategies as $strategy) { 
      if ($strategy->test($a, $b, $c, $d)) { 
       return $strategy->doStuff(); 
      } 
     } 
     throw new RuntimeException('Unhandleable Situation!'); 
    } 
} 

interface iDoStuffStrategy { 
    // Return a bool if you can handle this situation 
    public function test($a, $b, $c, $d); 
    // Execute the implementation 
    public function doStuff(); 
} 

फिर, प्रत्येक वर्ग इस प्रकार दिखाई देगा:

public function StrategyFoo implements iDoStuffStrategy { 
    public function test($a, $b, $c, $d) { 
     return $a && $b && $c && $d; 
    } 
    public function doStuff() { 
     //DoStuff! 
    } 
} 
public function StrategyBar implements iDoStuffStrategy { 
    public function test($a, $b, $c, $d) { 
     return !$a && $b && $c && $d; 
    } 
    public function doStuff() { 
     //DoStuff! 
    } 
} 

यह मूल रूप से Strategy Pattern के एक कार्यान्वयन है। ऐसा करने से आप निर्णय पेड़ को अलग कर सकते हैं।

+0

+1 इस दृष्टिकोण या कुछ इसी तरह के लिए कहा जाता है। जब भी आपके पास स्विच स्टेटमेंट का लंबा सेट होता है, तो शायद ओओपी स्टाइल सोच का उपयोग करना सबसे अच्छा होता है। – NotMe

+0

@ircmaxwell ... मैं इस कोड के एक संस्करण का उपयोग करने की कोशिश कर रहा हूं और अगर मैं कुछ खो रहा हूं तो उत्सुक हूं। 'AddStrategy' विधि ऑब्जेक्ट को' $ strategy' चर में कैसे जोड़ती है? मुझे वास्तव में इस डिजाइन पैटर्न से प्यार है और इसे लागू करना चाहते हैं, लेकिन मैं उस हिस्से को काम करने के लिए नहीं मिल सकता। – tollmanz

0

मैं आपके चार बूलियन को चार बिट्स के रूप में मानता हूं, इसलिए 0 और 15 के बीच एक पूर्णांक के रूप में। मैं 16 तत्वों के साथ एक सरणी बनाउंगा, और सरणी के प्रत्येक तत्व में फ़ंक्शन पॉइंटर संग्रहीत करूंगा। हर बार जब आपको ऐसा करने की ज़रूरत होती है, तो मैं बूलियन को थोड़ा पैटर्न में मूल्यांकन करता हूं, int में परिवर्तित करता हूं, और सरणी के उस इंडेक्स में संग्रहीत विधि को कॉल करता हूं।

मुझे पता है कि आप PHP के बारे में पूछ रहे हैं, जो मुझे डर है, मुझे नहीं पता। सी # में, आप ऐसा कुछ कर सकते हैं:

static class Multiplexer 
{ 
    public static string Multiplex(bool a, bool b, bool c, bool d) 
    { 
     var i = 0; 
     i |= (a ? 1 : 0) << 3; 
     i |= (b ? 1 : 0) << 2; 
     i |= (c ? 1 : 0) << 1; 
     i |= (d ? 1 : 0); 
     return _functions[i](); 
    } 

    private static Func<string>[] _functions = new Func<string>[] { 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return Assembly.GetExecutingAssembly().FullName; }, 
     () => { return ""; }, 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return Assembly.GetExecutingAssembly().FullName; }, 
     () => { return ""; }}; 
} 
संबंधित मुद्दे