दिलचस्प पोस्ट
मैं सर्विस स्टैक्स प्रमाणीकरण कैसे बढ़ा सकता हूं निरंतर सूचक बनाम पॉइंटर स्थिर मूल्य पर "Git add -A" और "git add" के बीच का अंतर। धागा का उपयोग कर अजीब संख्या छपाई Google नक्शे में मार्ग के मिडपॉइंट मैं एक सर्वलेट के लिए कैसे पारित यूनिकोड पैरामीटर सही ढंग से व्याख्या करूं बंडल के माध्यम से ऑब्जेक्ट कैसे भेजें सी / सी ++: सूचक अंकगणित मैं जावा में एक जेनेरिक फ़ील्ड का प्रकार कैसे निर्धारित करूं? रुको जब तक फ़ाइल में अनलॉक नहीं किया जाता है। NET क्या मैं UITextView पर ऑटो की गई लिंक का रंग बदल सकता हूँ? क्या कोई क्रॉस-डोमेन iframe ऊँचाई ऑटो-रीसाइज़र है जो काम करता है? C ++ में "const" के उपयोग के कितने और कौन हैं? जीपीएस समन्वय से दूरी जोड़ना PHP में फार्म POST से कर्ल के माध्यम से फाइल भेजें

अगर जावा में बयान की लंबी सूची

माफ करना, मुझे इसका उत्तर देने वाला कोई प्रश्न नहीं मिल सकता है, मैं लगभग निश्चित है कि किसी और ने इसे पहले उठाया है।

मेरी समस्या यह है कि मैं एम्बेडेड डिवाइस को चलाने के लिए कुछ सिस्टम लाइब्रेरी लिख रहा हूं मेरे पास ऐसे आदेश हैं जो रेडियो प्रसारणों पर इन उपकरणों को भेजा जा सकता है। यह केवल पाठ द्वारा किया जा सकता है सिस्टम लाइब्रेरी के अंदर मेरे पास एक धागा है जो इस प्रकार दिखने वाले कमांड को संभालता है I

if (value.equals("A")) { doCommandA() } else if (value.equals("B")) { doCommandB() } else if etc. 

समस्या ये है कि इसके बहुत सारे कमान हैं, वह जल्दी से कुछ नियंत्रण से बाहर निकल जाएंगे। देखने के लिए भयानक, डीबग करने के लिए दर्दनाक और कुछ महीनों के समय में समझने के लिए मस्तिष्क।

वेब के समाधान से एकत्रित समाधान "अगर जावा में बयान की लंबी सूची"

कमान पैटर्न का उपयोग कर:

 public interface Command { void exec(); } public class CommandA() implements Command { void exec() { // ... } } // etc etc 

फिर एक Map<String,Command> ऑब्जेक्ट का निर्माण करें और इसे Command इंस्टेंस के साथ पॉप्युलेट करें:

 commandMap.put("A", new CommandA()); commandMap.put("B", new CommandB()); 

तो आप अगर आपके साथ चेन को / if की जगह ले सकते हैं:

 commandMap.get(value).exec(); 

संपादित करें

आप UnknownCommand या NullCommand UnknownCommand जैसे विशेष आदेश भी जोड़ सकते हैं, लेकिन आपको CommandMap जरूरत है जो ग्राहक के चेक को कम करने के लिए इन कोने के मामलों को संभालता है।

अच्छी तरह से एक कमांड पैटर्न है लेकिन यह आप के लिए क्या कर रहे हैं overkill हो सकता है। चुंबन याद रखें

मेरा सुझाव enum और कमान ऑब्जेक्ट का एक हल्का संयोजन होगा। यह प्रभावी जावा के मद 30 में यहोशू ब्लॉच द्वारा सुझाए गए मुहावरे हैं।

 public enum Command{ A{public void doCommand(){ // Implementation for A } }, B{public void doCommand(){ // Implementation for B } }, C{public void doCommand(){ // Implementation for C } }; public abstract void doCommand(); } 

बेशक आप doCommand करने के लिए पैरामीटर पारित या वापसी के प्रकार हो सकता है।

यह समाधान वास्तव में उपयुक्त नहीं हो सकता है यदि doCommand के कार्यान्वयन वास्तव में "एंटम प्रकार" के लिए "फिट" नहीं है, जो हमेशा की तरह है – जब आपको एक ट्रेडऑफ करना पड़ता है – थोड़ा सा फजी।

डीएफए द्वारा सरल और स्पष्ट रूप से दिखाए गए इंटरफ़ेस को कार्यान्वित करना स्वच्छ और सुरुचिपूर्ण (और "आधिकारिक रूप से समर्थित") है। यह इंटरफ़ेस की अवधारणा के लिए क्या है

सी # में, हम उन प्रोग्रामरों के लिए प्रतिनिधि का उपयोग कर सकते हैं जो सी में मिक्कटन पॉइंटर्स का उपयोग करना चाहते हैं, लेकिन डीएफए की तकनीक का उपयोग करने का तरीका है।

आपके पास एक सरणी भी हो सकती है

 Command[] commands = { new CommandA(), new CommandB(), new CommandC(), ... } 

तब आप सूचकांक द्वारा एक आदेश निष्पादित कर सकते हैं

 commands[7].exec(); 

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

 abstract public class Command() { abstract public byte exec(String subCmd); public String cmdKey; public String subCmd; } 

इस प्रकार अपने आदेशों का निर्माण,

 public class CommandA extends Command { public CommandA(String subCmd) { this.cmdKey = "A"; this.subCmd = subCmd; } public byte exec() { sendWhatever(...); byte status = receiveWhatever(...); return status; } } 

फिर आप एक प्रमुख मूल्य जोड़ी चूसने वाले फ़ंक्शन को प्रदान करके सामान्य हैशमैप या हैशटेबल का विस्तार कर सकते हैं:

 public class CommandHash<String, Command> extends HashMap<String, Command> ( public CommandHash<String, Command>(Command[] commands) { this.commandSucker(Command[] commands); } public commandSucker(Command[] commands) { for(Command cmd : commands) { this.put(cmd.cmdKey, cmd); } } } 

फिर अपने कमांड स्टोर का निर्माण करें:

 CommandHash commands = new CommandHash( { new CommandA("asdf"), new CommandA("qwerty"), new CommandB(null), new CommandC("hello dolly"), ... }); 

अब आप नियंत्रणों को स्पष्ट रूप से भेज सकते हैं

 commands.get("A").exec(); commands.get(condition).exec(); 

कमांडों की एक संख्या है:

 public enum Commands { A, B, C; } ... Command command = Commands.valueOf(value); switch (command) { case A: doCommandA(); break; case B: doCommandB(); break; case C: doCommandC(); break; } 

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

अच्छी तरह से मैं कमांड ऑब्जेक्ट्स बनाने और स्ट्रिंग की कुंजी का उपयोग करके एक हैशप में डाल करने का सुझाव देता हूं।

यहां तक ​​कि अगर मुझे विश्वास है कि कमांड पैटर्न दृष्टिकोण बेहतर प्रतीत होता है और लंबे समय में रखरखाव करता है, तो यह आपके लिए एक एक लाइनर विकल्प है:

org.apache.commons.beanutils.MethodUtils.invokeMethod (यह, "doCommand" + मूल्य, नल);

मैं आमतौर पर इसे इस तरह हल करने की कोशिश करता हूं:

 public enum Command { A {void exec() { doCommandA(); }}, B {void exec() { doCommandB(); }}; abstract void exec(); } 

इसके कई फायदे हैं:

1) अंजाम कार्यान्वित किए बिना एक एन्यूम जोड़ना संभव नहीं है तो आप एक ए याद नहीं करेंगे

2) आपको इसे किसी भी कमांड मैप में भी जोड़ना नहीं होगा, इसलिए नक्शा बनाने के लिए कोई बॉयलरप्लेट कोड नहीं होगा। सिर्फ सार पद्धति और उसके कार्यान्वयन (जो यकीनन बॉयलरप्लेट भी है, लेकिन यह किसी भी छोटा नहीं होगा ..)

3) यदि आप हैशकोड की गणना और लुकअप करने की लंबी सूची के माध्यम से जाकर किसी भी बर्बाद सीपीयू चक्र को बचा लेंगे।

संपादित करें: यदि आपके पास स्रोत नहीं है लेकिन स्रोत के रूप में तार हैं, तो केवल Command.valueOf(mystr).exec() उपयोग करें Command.valueOf(mystr).exec() exec विधि को कॉल करने के लिए। ध्यान दें कि आपको किसी अन्य पैकेज से इसे कॉल करना चाहते हैं, तो उस पर सार्वजनिक संशोधक का उपयोग करना चाहिए।

संभवतया आप मैप ऑफ कमानों का उपयोग कर सर्वश्रेष्ठ हैं

लेकिन क्या आपके पास इनमें से एक सेट है जिसे आप मैप्स के भार के साथ समाप्त करने के लिए संभालने के बारे में बताते हैं। तो यह Enums के साथ ऐसा करने के लिए देख लायक है

यदि आप "मान" के लिए हल करने के लिए Enum करने के लिए एक विधि जोड़ते हैं, तो स्विच के बिना (आप संभवत: उदाहरण में गेटर्स की आवश्यकता नहीं है) एक ऐन्यू के साथ ऐसा कर सकते हैं। तो आप बस कर सकते हैं:

अद्यतन: प्रत्येक कॉल पर चलने से बचने के लिए स्थैतिक मानचित्र जोड़ा गया। इस जवाब से बेहद कुंठित

 Commands.getCommand(value).exec(); public interface Command { void exec(); } public enum Commands { A("foo", new Command(){public void exec(){ System.out.println(A.getValue()); }}), B("bar", new Command(){public void exec(){ System.out.println(B.getValue()); }}), C("barry", new Command(){public void exec(){ System.out.println(C.getValue()); }}); private String value; private Command command; private static Map<String, Commands> commandsMap; static { commandsMap = new HashMap<String, Commands>(); for (Commands c : Commands.values()) { commandsMap.put(c.getValue(), c); } } Commands(String value, Command command) { this.value= value; this.command = command; } public String getValue() { return value; } public Command getCommand() { return command; } public static Command getCommand(String value) { if(!commandsMap.containsKey(value)) { throw new RuntimeException("value not found:" + value); } return commandsMap.get(value).getCommand(); } } 

@ डीएफए द्वारा दिए गए उत्तर मेरे विचार में सबसे अच्छा समाधान है।

मैं सिर्फ कुछ स्निपेट प्रदान कर रहा हूं अगर आप जावा 8 का उपयोग कर रहे हैं और लैम्ब्डा का उपयोग करना चाहते हैं!

पैरामीटर के बिना कमांड:

 Map<String, Command> commands = new HashMap<String, Command>(); commands.put("A", () -> System.out.println("COMMAND A")); commands.put("B", () -> System.out.println("COMMAND B")); commands.put("C", () -> System.out.println("COMMAND C")); commands.get(value).exec(); 

(आप कमान के बजाए एक रननबल का उपयोग कर सकते हैं, लेकिन मैं इसे सही शब्दों में नहीं मानता):

एक पैरामीटर के साथ कमांड:

यदि आप पैरामीटर की अपेक्षा करते हैं तो आप java.util.function.Consumer उपयोग कर सकते हैं:

 Map<String, Consumer<Object>> commands = new HashMap<String, Consumer<Object>>(); commands.put("A", myObj::doSomethingA); commands.put("B", myObj::doSomethingB); commands.put("C", myObj::doSomethingC); commands.get(value).accept(param); 

उपरोक्त उदाहरण में, doSomethingX एक myObj के वर्ग में मौजूद एक विधि है जो तर्क के रूप में किसी ऑब्जेक्ट (इस उदाहरण में param नाम) लेता है।

यदि आपके पास कई 'इमेज' स्टेटमेंट हैं, तो यह एक नियम इंजन का उपयोग करने के लिए एक पैटर्न है। देखें, उदाहरण के लिए जेबोस ड्रोओल्स

बस एक हैशमैप का उपयोग करें, जैसा कि यहां बताया गया है:

अगर प्रक्रियाओं की सरणी (जिसे आप कमांड कहते हैं) के लिए संभव है जो कि उपयोगी होगा ..

लेकिन आप अपना कोड लिखने के लिए एक प्रोग्राम लिख सकते हैं यह बहुत व्यवस्थित है अगर (मान = 'ए') कमांड ए (); और अगर (…………………… आदि

मुझे यकीन नहीं है कि आपके पास विभिन्न आदेशों के व्यवहार के बीच कोई ओवरलैप है, लेकिन आप दायित्व की चेन पर एक नज़र रखना चाह सकते हैं जो कई आदेशों को कुछ इनपुट मूल्यों को संभालने के द्वारा अधिक लचीलापन प्रदान कर सकते हैं।

अगर यह कई चीजें करता है, तो बहुत सारे कोड होंगे, आप वास्तव में उस से दूर नहीं जा सकते बस का पालन करना आसान बनाओ, चर को बहुत ही अर्थपूर्ण नाम दें, टिप्पणियां भी मदद कर सकती हैं …