2014-10-26 18 views
7

के साथ तर्क/अन्य तर्क को बदलकर मैंने जावा में सशर्त तर्क को बदलने पर पिछले स्टैक एक्सचेंजों को पढ़ा है जैसे आईएफ/ईएलएसई राज्य/रणनीति पैटर्न के साथ, लेकिन मुझे यकीन नहीं है कि मेरा मामला उचित फिट है या नहीं प्रतिस्थापन। यहाँ मिलकर कर रहे हैं मैं को देखा - Long list of if statements in Java और Converting many 'if else' statements to a cleaner approachराज्य/रणनीति पैटर्न

मैं अनिवार्य रूप से एक फ़ाइल डाउनलोड प्रबंधक लिख रहा हूँ और ये हैं मेरी यदि/और निर्माण करती है:

  1. फ़ाइल हैं और यह ज़िप फ़ाइल है तो ज़िप फ़ाइल के लिए कदम मौजूद ज़िप फ़ाइल निर्देशिका करने के लिए और फ़ाइल
  2. में पढ़ा ज़िप फ़ाइल मौजूद है, तो उसके बाद फ़ाइल अनज़िप और ज़िप फ़ाइल निर्देशिका में ज़िप फ़ाइल ले जाएँ और फ़ाइल
  3. में पढ़ा ज़िप फ़ाइल तो मौजूद नहीं है निर्दिष्ट URL से डाउनलोड और उसके बाद इसे अनजिप करें और पढ़ें फ़ाइल और निर्दिष्ट निर्देशिका में ज़िप फ़ाइल ले जाएँ।
  4. यदि ज़िप फ़ाइल यूआरएल में मौजूद नहीं है तो रिक्त फ़ाइल बनाएं और इसे डिस्क पर लिखें।

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

उत्तर

4

मुझे लगता है कि आपको गोफ पैटर्न Chain of responsibility का उपयोग करना चाहिए। आपको दो इंटरफेस पेश करना चाहिए: 1) Condition जहां आप उचित स्थिति की जांच करेंगे, उदा। "यदि ज़िप फ़ाइल मौजूद नहीं है" और वापस बूलियन परिणाम - "सत्य" अगर स्थिति संतुष्ट है, अन्यथा "अन्य", 2) Execution strategy, जो शर्त के साथ असाइन की गई कार्रवाई चलाएगी, उदाहरण के लिए "इसे निर्दिष्ट यूआरएल से डाउनलोड करें और फिर इसे अनजिप करें और फ़ाइल में पढ़ें और ज़िप निर्देशिका को निर्दिष्ट निर्देशिका में ले जाएं।" तो, पहला इंटरफ़ेस "कब", और दूसरा - "फिर" प्रश्न का उत्तर देगा। "हालत" कार्यान्वयन और "निष्पादन रणनीति" कार्यान्वयन को "tuple" (या जोड़ी, प्रविष्टि, आदि) में जोड़ा जाना चाहिए। इस "tuple" को क्रम में संग्रहीत करने के लिए स्थानांतरित किया जाना चाहिए, जिसे आपने वर्णित किया है। फिर, जब आपको ज़िप फ़ाइल को संभालने की आवश्यकता होती है, तो आप संग्रह पर पुन: प्रयास करेंगे, परिस्थितियों का आह्वान करेंगे और परिणाम जांचेंगे, यदि परिणाम "सत्य" है तो उपयुक्त "निष्पादन रणनीति" का आह्वान करें। इसके अलावा, स्थिति निष्पादन रणनीति के साथ जोड़ा जा सकता है और दो तरीकों के साथ एकल इंटरफ़ेस/कार्यान्वयन में स्थानांतरित किया जा सकता है। संदर्भ, जो ज़िप फ़ाइल की वर्तमान स्थिति का वर्णन करेगा, शर्तों/निष्पादन रणनीतियों के बीच पारित किया जा सकता है। उम्मीद है कि यह मदद करता है।

अद्यतन। कोड उदाहरण (जावा में)।

/** 
* All implementations should check proper condition 
*/ 
interface Condition { 

    /** 
    * Check if condition is satisfied 
    * 
    * @param pathToFile path to target file 
    * @return 'true' if condition is satisfied, otherwise 'false' 
    */ 
    boolean isSatisfied(String pathToFile); //i've made an assumption that you'll manipulate file path for checking file 
} 
... 
/** 
* Childs will wrap some portion of code (if you'll use language, that supports lambdas/functors, this interface/implementation can be replaced with lambda/functor) 
*/ 
interface Action { 

    /** 
    * Execute some portion of code 
    * 
    * @param pathToFile path to target file 
    */ 
    void execute(String pathToFile); 
} 
... 
class ZipFileExistsCondition implements Condition { 

    @Override 
    public boolean isSatisfied(String pathToFile) { 
    ... //check if zip file exists 
    } 
} 
... 
class ZipFileDoesNotExists implements Condition { 
    @Override 
    public boolean isSatisfied(String pathToFile) { 
    ... //download zip file and move it to some temp directory 
    //if file downloaded ok, than return 'true' otherwise 'false' 
    } 
} 
... 
class AlwaysSatisfiedCondition implements Condition { 
    @Override 
    public boolean isSatisfied(String pathToFile) { 
    ... //always returns 'true', to run action assigned with this condition 
    } 
} 
... 
Collection<Map.Entry<Condition, Action>> steps = Arrays.asList(
new AbstractMap.ImmutableEntry<Condition, Action>(new ZipFileExistsCondition(), 
new Action() { /*move zip file to zip file directory and read in file*/ }), 
new ZipFileDoesNotExists(), new Action() { /*download it from specified URL and then unzip it and read in file and move zip file to specified directory*/ }, 
new AlwaysSatisfiedCondition(), new Action() { /*create blank file and write it out to disk*/ } 
); 
... 
String pathToFile = ... 
... 
for(Map.Entry<Condition, Action> step: steps) { 
if(!step.getKey().isSatisfied(pathToFile)) 
    continue; 

step.getValue().execute(pathToFile); 
} 

टिप्पणी: 1) आप गुमनाम वर्ग के रूप में 'स्थिति' लागू कर सकते हैं, 2) 'AlwaysSatisfiedCondition' सिंगलटन हो सकता है, 3) यदि आप जावा/ग्रूवी/स्काला का उपयोग कर रहे हैं, तो आप अमरूद उपयोग कर सकते हैं/'एक्शन' के बजाय 'कंडीशन', 'फंक्शन' या 'क्लोजर' के बजाय अपाचे कॉमन्स 'प्रीडिकेट'।

यदि आपको पहली 'संतुष्ट' स्थिति और उपयुक्त कार्रवाई निष्पादन के बाद बाहर निकलने की आवश्यकता है तो कार्रवाई निष्पादन के बाद बस 'ब्रेक'/'रिटर्न' डालें।

+0

उस प्रतिक्रिया के लिए धन्यवाद। जैसा कि मैं आपका जवाब समझता हूं, आप मुझे संग्रह को पुन: स्थापित करने के लिए चाहते हैं और फिर यह देखने के लिए एक कथन बनाते हैं कि कौन सी रणनीति को सही करने की आवश्यकता है? – gansub

+0

नहीं। आपको संग्रह पर पुन: प्रयास करना चाहिए और प्रत्येक "condition.is संतुष्ट" पूछना चाहिए, इसलिए कोई भी "if/then/else" कथन नहीं होगा, लेकिन प्रत्येक "स्थिति" "कथन" लपेट जाएगी। – nndru

+0

ग्रेट। तो यहां मुख्य बिंदु पुनरावृत्ति के लिए "आदेश" है। एक बार आदेश तय हो जाने के बाद यह सीधा है। तो बस अधिक स्पष्टता के लिए मेरे पास FileReadCondition है जो कंडीशन और FileReadExecution लागू करता है जो निष्पादन लागू करता है। FileReadCondition FileReadExecution को प्रतिनिधि करता है? शायद कुछ कोड मदद करेगा। – gansub

1

इस कोड को संकलित करने का उचित तरीका निम्नलिखित है। यहां मुख्य बिंदु यह है कि AbstractMap.SimpleImmutableEntry एक एकल प्रविष्टि है। यदि आप और प्रविष्टियां जोड़ना चाहते हैं तो आपको प्रत्येक प्रविष्टि के लिए कक्षा को तुरंत चालू करने की आवश्यकता है।

Collection<Map.Entry<Condition,Action>> steps = Arrays.asList 
    (
    (new AbstractMap.SimpleImmutableEntry<Condition,Action> 
     (new FileExistsCondition(), 
     new Action() 
     { 
     public void execute(String pathToFile){System.out.println("the path to file is srtm " + pathToFile);} 
     } 
     ) 
    ), 
    (new AbstractMap.SimpleImmutableEntry<Condition,Action> 
     (new ZipFileExistsCondition(), 
     new Action() 
     { 
     public void execute(String pathToFile){System.out.println("the path to file is " + pathToFile);} 
     } 
     ) 
    ), 
    (new AbstractMap.SimpleImmutableEntry<Condition,Action> 
     (new ZipFileDoesNotExistCondition(), 
     new Action() 
     { 
     public void execute(String pathToFile){System.out.println("the path to file is " + pathToFile);} 
     } 
    ) 
    ) 
    ); 
संबंधित मुद्दे