2011-01-15 19 views
8

हम जावा में श्रोताओं प्रयोग करने के लिए सबसे अच्छा अभ्यास है क्या के बारे में काम पर एक बहस की थी: चाहे श्रोता तर्क, अनाम कक्षा में रहना चाहिए या यह एक अलग विधि में होना चाहिए, उदाहरण के लिए:जावा: मुझे अनाम श्रोता लॉग इन कोड कहां रखना चाहिए?

button.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     // code here 
    } 
}); 

या

button.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     buttonPressed(); 
    } 
}); 

private void buttonPressed() { 
    // code here 
} 

जो पठनीयता और रखरखाव के मामले में अनुशंसित तरीका है? मैं श्रोता के अंदर कोड रखना पसंद करता हूं और केवल तभी बड़ा होता है, इसे एक आंतरिक वर्ग बनाते हैं। यहां मुझे लगता है कि कोड कहीं और डुप्लिकेट नहीं है।

धन्यवाद।

उत्तर

4

मेरे आत्म लगाया नियम है: श्रोता अधिक से अधिक 2 तरीकों है

  1. हैं, तो एक नामित वर्ग पैदा करते हैं।
  2. यदि श्रोता 10 से अधिक लाइनों को फैलाता है, तो नामित कक्षा बनाएं।

बहुत आसान, पालन करने में आसान और कम या कम पठनीय कोड उत्पन्न करता है। लेकिन फिर मुझे यह मानना ​​है कि मैंने कभी भी सोचा नहीं कि आपका उदाहरण क्या दिखाता है।

+0

अंगूठे के कुछ अच्छे नियम। 1+ –

+1

मैं एक नामित आंतरिक वर्ग का उपयोग करता हूं, और पंजीकरण के दौरान कोड obfuscation को रोकने के लिए उनमें से बहुत से हैं, तो छोटे श्रोताओं के लिए भी उन्हें बनाने के लिए जाते हैं। तो यह मेरे लिए एक तीसरा मानदंड होगा। – extraneon

1

मेरी व्यक्तिगत राय में, "यह निर्भर करता है"। यदि श्रोता केवल एक घटक में जोड़ा जाना है, तो यह बहुत आसान है और जीयूआई का एक अभिन्न अंग है, फिर एक अज्ञात भीतरी कक्षा अच्छी तरह से काम करेगी। यदि श्रोता जटिल है, तो कई घटकों में जोड़ा जाएगा, इसका अपना अलग राज्य होगा, फिर एक अलग स्टैंड अकेले वर्ग बेहतर होगा। बीच में निजी आंतरिक वर्ग है। HTH।

संपादित करें: मेरा बुरा। मैं एक अलग प्रश्न का उत्तर दे रहा था - श्रोता के लिए एक अलग स्टैंड-अलोन क्लास का उपयोग करना है या नहीं। एक विधि में एनन आंतरिक कक्षा कोड इनलाइन बनाम रखने के लिए, मैं दूसरे पोस्टर से सहमत हूं, यह श्रोता कोड के आकार और जटिलता पर निर्भर करेगा।

2

यह सवाल आंशिक रूप से यहां उत्तर दिया जाता है:
1) आप आसानी से कोड को फिर से उपयोग कर सकते हैं तो आप पा सकते हैं:

Is there a better practice for listeners

मैं भी दो कारणों के लिए बेनामी तरीका पसंद नहीं है कि आपके पास थोड़ी देर के बाद डुप्लिकेट कोड है 2) मुझे लगता है कि यह कोड के पढ़ने को तोड़ देता है (अन्य असहमत ... व्यक्तिगत स्वाद)। मुझे लगता है कि हर कोई इस बात से सहमत होगा कि यदि आप 5-10 से अधिक लाइनें कर रहे हैं कि अज्ञात आंतरिक वर्ग एक अच्छा विचार नहीं है (मैं कहूंगा कि 2 से अधिक बहुत अधिक है)।

+0

+1 - आप किसी अज्ञात विधि में कोड का पुन: उपयोग नहीं कर सकते हैं। – jmort253

+0

निश्चित रूप से आप कर सकते हैं। बस बटन से श्रोता प्राप्त करें और इसे किसी अन्य श्रोता में लपेटें :) बिल्कुल सही उपयोग (हालांकि रखरखाव योग्य नहीं है :) – extraneon

+1

निश्चित रूप से आप केवल उदाहरण का पुन: उपयोग कर सकते हैं। एक्शन एक्शन = नई एक्शन ("गो") {...}, तो आप इसे बटन, मेनू या एक्शन मैप पर असाइन कर सकते हैं। उदाहरण का पुन: उपयोग करके पुन: उपयोग करने में कोई समस्या नहीं है। आप इसे श्रोताओं से भी हटा सकते हैं। – chubbsondubs

1

यदि विधि buttonPressed() को अज्ञात भीतरी कक्षा से अलग किसी भी चीज़ से कभी भी एक्सेस करने की आवश्यकता होगी, तो एक विधि का उपयोग करें। अन्यथा बस कोड को actionPerformed() में रखें।

+0

सहमत हैं। आईडीई में रिफैक्टरिंग के साथ हासिल करने के लिए अच्छा और आसान है। – Xorty

1

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

उदाहरण के लिए:

public class Model { 
    private final Action buttonAction; 
    ... 

    public Model(final IController controller) { 
     buttonAction = createButtonAction(controller); 
     ... 
    } 

    private Action createButtonAction(final IController controller) { 
     Action action = new Action("Action") { 
      public void actionPerformed(final ActionEvent e) { 
       // do the required action with long running ones on a separate Thread 
       controller.run(); 
      } 
     }; 
     action.set...// other initialisation such as icon etc 
     ... 
     return action; 
    } 
    ... 

    public Action getButtonAction() { 
     return buttonAction; 
    } 
} 

दृश्य भी एक अलग वर्ग है, जो अपने निर्माता पैरामीटर, जहां वास्तविक बटन इन्स्टेन्शियशन जगह लेता है के रूप में मॉडल लेता है का प्रतिनिधित्व करती है। उदाहरण के लिए:

public class View extends JPanel { 
    public View(final Model model) { 
     ... 
     JButton button = new JButton(model.getButtonAction(); 
     ... 
    } 
} 

इस दृष्टिकोण के साथ यह बाद से यह बहुत पुनः उपयोग किया जा के बराबर है actionPerformed के तर्क गुमनाम वर्ग के हिस्से के रूप लागू करने के लिए काफी सुविधाजनक है। सभी तर्क नियंत्रक में encapsulated है, तो कार्रवाई वास्तव में एक बटन के लिए मॉडल के रूप में इस्तेमाल करने के लिए नियंत्रक कॉल के चारों ओर एक रैपर के रूप में सेवा करते हैं।

0

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

Action action = new AbstractAction("Open") {...}; 
JButton button = new JButton(action); 
JMenuItem menuItem = new JMenuItem(action); 
panel.getActionMap().put("openFile", action); 

अब आप उस क्रिया को कई घटकों में पुन: उपयोग कर सकते हैं। मेमोरी लीक की बाद की समस्या के लिए आप इसे संदर्भित करने के लिए उस संदर्भ का उपयोग कर सकते हैं, या दूसरा और सरल विकल्प WeakListeners है। WeakListeners के पास उनके निर्माण के बाद प्रबंधित करने की आवश्यकता नहीं है।

शैली के लिए मुझे बेनामी श्रोताओं को काफी आसान लगता है, और कुछ मामलों में स्विंग में थ्रेडिंग से निपटने के दौरान पढ़ने में आसान होता है क्योंकि यह आपके कोड को एक विधि (InvokeLater, executeInBackground, आदि) में रखता है। जब आप एनन श्रोता एक उदाहरण विधि में प्रतिनिधि होते हैं तो मुझे लगता है कि यह कोड को अलग करता है जहां आप श्रोता से पहले क्या हुआ और एक स्क्रीन में श्रोता से जुड़े तर्क को पढ़ नहीं सकते हैं। वे अलग हो जाते हैं, और इसका पालन करना कठिन होता है।

कुछ पता होना चाहिए कि यदि आप एक्शनमैप्स का उपयोग करते हैं तो अधिकांश मेमोरी लीक कुंजीपटल सुनने से जुड़े हो जाएंगे। दुर्भाग्य से केंद्रीय प्रणालियों के साथ पंजीकृत फोकस श्रोताओं या श्रोताओं जैसी चीजें अभी भी एक समस्या है। (फिर से WeakListeners यहां महान हैं)। और आपके पास पहले से ही प्रत्येक घटक के साथ कार्रवाई रखने के लिए एक जगह है इसलिए इसे पकड़ने के लिए अतिरिक्त आवृत्ति चर बनाने की आवश्यकता नहीं है। यदि आपको दो घटकों (मेनू बार में और नियंत्रण में कहें) में पुन: उपयोग करने की आवश्यकता है तो एक अलग वर्ग बनाएं।

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