2010-05-24 9 views
10

मेरे पास findByCriteria विधि के साथ इंटरफ़ेस ProductService है। इस विधि में productName, maxCost, minCost, producer और इसी तरह के नालीबल पैरामीटर की एक लंबी सूची थी।क्या जावा में इंटरफेस के अंदर नेस्टेड क्लास घोषित करने में कुछ बुरा है?

मैंने Parameter Object पेश करके इस विधि को दोबारा प्रतिक्रिया दी। मैं कक्षा SearchCriteria बनाया है और अब विधि हस्ताक्षर इस तरह दिखता है:

findByCriteria (SearchCriteria criteria) 

मैंने सोचा था कि SearchCriteria के उदाहरण केवल, विधि कॉल द्वारा बनाई गई हैं और केवल findByCriteria विधि के अंदर उपयोग किया जाता है अर्थात्:

void processRequest() { 
    SearchCriteria criteria = new SearchCriteria() 
            .withMaxCost (maxCost) 
            ....... 
            .withProducer (producer); 

    List<Product> products = productService.findByCriteria (criteria); 
    .... 
} 

और

List<Product> findByCriteria(SearchCriteria criteria) { 
    return doSmthAndReturnResult(criteria.getMaxCost(), criteria.getProducer());  
} 

तो मैं SearchCriteria के लिए एक अलग सार्वजनिक कक्षा नहीं बनाना चाहता था और इसेके अंदर रखूं:

public interface ProductService { 
    List<Product> findByCriteria (SearchCriteria criteria); 

    static class SearchCriteria { 
     ... 
    } 
} 

क्या इस इंटरफ़ेस के साथ कुछ बुरा है? आप SearchCriteria कक्षा कहां रख सकते हैं?

+3

आपको सर्चक्रिटिया को स्थैतिक, सभी सदस्य प्रकार के इंटरफेस के रूप में चिह्नित करने की आवश्यकता नहीं है निहित स्थिर (और सार्वजनिक) हैं। – Oak

उत्तर

3

मुझे लगता है कि यह अच्छा लग रहा है। यह स्पष्ट रूप से संकेत करता है कि SearchCriteria विशेष रूप से ProductService एस के साथ उपयोग के लिए है।

हालांकि कुछ लोग तर्क देंगे कि घोंसला वाले वर्ग थोड़ा अजीब दिखते हैं और दावा करते हैं कि यह एक अधिक डिज़ाइन होगा और पैकेज-स्कोप इस सहित अधिकांश मामलों में पर्याप्त है।

2

यह बुरा नहीं है, और यदि आप इंटरफेस और कुछ उपयोगिता वस्तुओं, जैसे तुलनाकर्ताओं के बीच एक कठिन समूह चाहते हैं तो उपयोगी हो सकते हैं। (मैंने एक इंटरफ़ेस के साथ बिल्कुल वही किया है, और आंतरिक कक्षाएं उपयोगी तुलनाकर्ताओं को प्रदान करती हैं जो इंटरफ़ेस के उदाहरणों की तुलना करती हैं।)

यह ग्राहकों के उपयोग के लिए थोड़ा अजीब हो सकता है, क्योंकि उन्हें आंतरिक कक्षा के नाम को उपसर्ग करना होगा इंटरफ़ेस नाम (या एक स्थिर आयात का उपयोग करें), लेकिन एक अच्छा आईडीई आपके लिए इसका ख्याल रखता है (लेकिन कोड को Interface.SomeClass घोषणाओं के साथ मिर्च किया जा सकता है, जो बहुत अच्छा नहीं लग रहा है।)

हालांकि, विशिष्ट में मामला, SearchCriteria इंटरफ़ेस के साथ इतना कसकर नहीं दिखता है, इसलिए यह एक नियमित पैकेज वर्ग के रूप में अधिक उपयोग योग्य हो सकता है।

2

मैं आपको कक्षाओं का उपयोग करने के लिए प्रोत्साहित करता हूं जब आपके पास ऐसी विधियां होती हैं जिनके लिए कम या कम नामुमकिन तर्क की आवश्यकता हो सकती है; यह आप की तरह एक विधि कॉल करने के बिना प्रदान करने के लिए जो कुछ भी आप की जरूरत की क्षमता देता है:

someMethod("foo", null, null, null, null, null, null, ..., "bar"); 

ऐसे mecanism का उपयोग करना, विधि कॉल होगा कुछ की तरह: दूसरी विधि

someMethod(new ObjParam().setFoo("foo").setBar("bar")); 

मरणासन्न हो और पुन: प्रयोज्य (विधि के ओवरराइड के बिना)। और मैं यहाँ नहीं कह रहा हूं कि विधि ओवरराइड खराब है! काफी विपरीत। हालांकि कई वैकल्पिक तर्कों के साथ, मैं दूसरी कॉल पसंद करूंगा।

इनर क्लासों का सवाल है, वे समय पर उपयोगी होते हैं, लेकिन मैं व्यक्तिगत रूप से इन दिशा-निर्देशों का पालन करें: इनर क्लासों का उपयोग करने के

  1. कोशिश केवल जब भीतरी वर्ग निजी (पूर्व किया जाना चाहिए: एक कस्टम के मामले में लिंक्डलिस्ट कार्यान्वयन, नोड क्लास एक निजी वर्ग है और इसलिए एक आंतरिक वर्ग है।)
  2. आमतौर पर केवल तभी कक्षा को पुन: प्रयोज्य नहीं किया जाता है और मुख्य रूप से कक्षाओं के एक छोटे से समूह के भीतर उपयोग किया जाता है जिसे मैं इसे एक आंतरिक कक्षा
  3. बना दूंगा
  4. "अभिभावक" और आंतरिक वर्ग काफी बड़ा हो जाता है; तो दोनों वर्गों को पठनीयता के लिए अपनी स्वयं की जावा स्रोत फ़ाइल दी जाती है, जब तक कि आंतरिक वर्ग को पहले बिंदु के रूप में निजी न हो।

ध्यान रखें कि, भीतरी वर्ग या नहीं, जावा कम्पाइलर हर वर्ग के लिए एक .class पैदा करेगा में रखें। जितना अधिक आप उनका उपयोग करेंगे, उतना ही कम पठनीय आपका कोड होगा। यह तय करने के लिए आप पर बहुत अधिक निर्भर है कि वे उचित हैं या नहीं ...

0

मुझे डर है कि मैं खराब के लिए मतदान करना चाहता हूं। वैसे भी काफी बुरा, आप बदतर चीजें कर सकते हैं ...

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

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

+0

ProductServiceImpl क्लास के अंदर कोई मानदंड श्रेणी परिभाषा नहीं है। यह ProductService इंटरफ़ेस के अंदर परिभाषित किया गया है। – Roman

+0

हम्म, अनुमान है कि मैंने आपके मूल कोड की तुलना में - आंतरिक कक्षाओं के मुद्दे पर - अधिक प्रतिक्रियाएं पढ़ी हैं। आपकी मानदंड कक्षा सार्वजनिक सेवा हस्ताक्षर में है, इसलिए ग्राहक द्वारा भरा जाता है। मुझे पता है कि ज्यादातर लोग इसे नियमित सार्वजनिक वर्ग के रूप में लिखेंगे - इसके बाद इसका सार्वजनिक उपयोग होता है। – StripLight

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

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