2010-11-02 22 views
20

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

  1. एक वस्तु स्थिर कारखाने विधि द्वारा वापस की कक्षा nonpublic है - वास्तव में क्या यह मतलब है?
  2. रचनाकारों के विपरीत स्थिर फैक्ट्री विधियों को प्रत्येक बार जब वे बुलाए जाते हैं तो एक नई वस्तु बनाने की आवश्यकता नहीं होती है - यह कैसे होता है? मैं केवल एक नई वस्तु प्राप्त करने के लिए फैक्ट्री विधि का आह्वान कर रहा हूं और क्या हम ऑब्जेक्ट पहले से मौजूद है या नहीं, यह जांचने के लिए कारखाने विधि में चेक डालते हैं?

धन्यवाद।

+2

सॉफ़्टवेयर डिज़ाइन अभ्यास में गहरे डाइविंग के लिए +1 और एक अच्छा प्रश्न पूछना। –

+0

धन्यवाद ब्रायन :) – t0mcat

+0

+1 लिखने के बजाय क्यों लिखने के बजाय प्रोग्रामिंग करने के बजाय। एक अच्छा कोडर की आदत। – TreyE

उत्तर

11

स्थैतिक फैक्ट्री विधि द्वारा लौटाई गई वस्तु का वर्ग गैर-सार्वजनिक - इसका क्या अर्थ है?

इसका मतलब है कि एक स्थिर फैक्ट्री विधि द्वारा लौटाई गई वस्तुओं की वास्तविक श्रेणी घोषित प्रकार का उप-वर्ग हो सकती है, और इस सबक्लास को सार्वजनिक होना आवश्यक नहीं है। यह सिर्फ एक और कार्यान्वयन विस्तार है कि क्लाइंट कोड की परवाह नहीं करनी चाहिए।

रचनाकारों के विपरीत स्थिर फैक्ट्री विधियों को प्रत्येक नई वस्तु बनाने के लिए आवश्यक नहीं है> समय-समय पर उन्हें बुलाया जाता है - यह कैसे होता है? मैं केवल एक नई वस्तु प्राप्त करने के लिए फैक्ट्री विधि का आह्वान कर रहा हूं और क्या हम ऑब्जेक्ट पहले से मौजूद है या नहीं, यह जांचने के लिए कारखाने विधि में चेक डालते हैं?

हां, यह एक ऐसा तरीका है जिसे किया जा सकता है। लेकिन वास्तव में, कुछ भी संभव है।

+0

हाय माइकल, तो यह आवश्यकताओं पर निर्भर करता है? कोई कठोर और तेज़ नियम नहीं है कि फैक्ट्री विधियों को हमेशा पहले से मौजूद उदाहरण की जांच करनी चाहिए। – t0mcat

+0

@ t3ch: हाँ, बिल्कुल। मुद्दा यह है कि आप कारखाने के तरीकों के साथ _can_ ऐसा करते हैं यदि यह उपयोगी है और आप क्या करना चाहते हैं ... आपके पास 'नया' वाला विकल्प नहीं है। – ColinD

+0

वाह धन्यवाद। कम से कम अब मुझे पता है कि यह उपयोगी होगा। इस दृष्टिकोण के साथ सिंगलेटन को बेहतर ढंग से समझा जा सकता है। – t0mcat

2

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

+0

>> यदि विधि एक नया उदाहरण बना रही है या संभवतः कुछ और कर रही है। अमीर, यदि स्थैतिक विधि एक नया उदाहरण नहीं बना रही है या नया ऑब्जेक्ट वापस नहीं कर रही है, तो हमें एक स्थिर फैक्ट्री विधि क्यों चाहिए? – t0mcat

+2

आपको हमेशा किसी चीज़ का एक नया उदाहरण नहीं चाहिए। उदाहरण के लिए, डेटाबेस कनेक्शन लें: आप जावा jdbc.newConnection() में करते हैं। लेकिन जावा हर बार एक नया उदाहरण नहीं बनाते हैं। यह पहले यह देखने के लिए जांच करता है कि कोई कनेक्शन पहले से मौजूद है या नहीं। यदि नहीं, तो यह एक नया उदाहरण मिलेगा। एक और उदाहरण यह हो सकता है कि आप एक सिंगलटन बनाना चाहते हैं। (सिंगलेट्स की अपनी समस्या है) जिसका अर्थ है कि एक अच्छा पढ़ा गया है कि कक्षा के केवल एक बार उदाहरण क्यों होना चाहिए। तो फिर आप अपने कन्स्ट्रक्टर को निजी बना देंगे और केवल स्थिर एपीआई के माध्यम से आपके एपीआई का उपयोग करने की अनुमति देंगे। –

+0

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

1

वर्ग nonpublic है

बार-बार एक स्थिर कारखाने विधि या तो एक एक वस्तु एक इंटरफेस (सबसे सामान्य), या कभी कभी कुछ आधार वर्ग के रूप में लिखा जाता है (कम वापस आ जाएगी सामान्य)। किसी भी मामले में, आप लौटे ऑब्जेक्ट की सटीक कक्षा को नहीं जानते हैं।

इसका लाभ उस वस्तु को प्राप्त कर रहा है जिसका व्यवहार आप बिना किसी कक्षा के गन्दा विवरण के बारे में चिंता किए बिना जानते हैं।

कंस्ट्रक्टर्स के विपरीत स्थिर कारखाने तरीकों जब भी

लागू कर रहे हैं यह समझने के लिए, एक सिंगलटन के साथ काम करने के मामले पर विचार के लिए एक नई वस्तु बनाने की आवश्यकता नहीं है। आप कुछ कारखाने वर्गों पर .getInstance() को किसी निश्चित ऑब्जेक्ट के सिंगलटन उदाहरण प्राप्त करने के लिए कॉल कर सकते हैं।आम तौर पर, यह क्या करता है ऑब्जेक्ट का एक उदाहरण बना देता है यदि यह पहले से मौजूद नहीं है, या यदि आप पहले से ही कर चुके हैं तो मौजूदा उदाहरण दें। किसी भी मामले में, आप वस्तु की एक प्रति वापस प्राप्त करते हैं। लेकिन आप यह नहीं जानते (और नहीं करेंगे) यह सिंगलटन बनाया जाना था, या यदि पहले से ही पहले से ही बनाया गया था।

इसका लाभ यह है कि वस्तु का जीवन चक्र और जब इसे बनाया जाता है तो यह आपके लिए प्रबंधित होता है।

+0

हाय ट्रे, आपका सिंगलटन उदाहरण वास्तव में मेरे संदेह को मंजूरी दे दी। धन्यवाद :) – t0mcat

0

कुछ प्रश्नों को देखकर आपके दोनों प्रश्नों का उत्तर दिया जा सकता है जो स्थिर कारखाने के तरीकों के इन दोनों गुणों का उपयोग करते हैं। मेरा सुझाव है कि अमरूद के ImmutableList पर विचार करें।

नोट करें कि नो-एर्ग फैक्ट्री विधि of() हमेशा एक ही उदाहरण देता है (यह हर बार एक नया उदाहरण नहीं बनाता है)। यदि आप ध्यान से देखते हैं, तो आप यह भी देखेंगे कि इसकी copyOf(Iterable) फ़ैक्टरी विधि वास्तव में उस ऑब्जेक्ट को वापस लौटाती है जो उस पर पारित होती है यदि वह ऑब्जेक्ट स्वयं ImmutableList है। इनमें से दोनों इस तथ्य का लाभ उठा रहे हैं कि ImmutableList कभी भी बदलने की गारंटी नहीं है।

सूचना भी है कि यह कैसे में विभिन्न कारखाने के तरीकों, इस तरह के , SingletonImmutableList और RegularImmutableList के रूप में विभिन्न उपवर्गों लौटने के लिए, उन वस्तुओं के प्रकार प्रकट किए बिना। विधि हस्ताक्षर केवल दिखाते हैं कि वे ImmutableList लौटाते हैं, और ImmutableList के सभी उप-वर्गों में पैकेज-निजी (डिफ़ॉल्ट) दृश्यता होती है, जिससे उन्हें लाइब्रेरी उपयोगकर्ताओं के लिए अदृश्य बना दिया जाता है। यह उपयोगकर्ता के परिप्रेक्ष्य से कोई जटिलता जोड़ने के बिना कई कार्यान्वयन कक्षाओं के सभी फायदे देता है, क्योंकि उन्हें केवल एक ही प्रकार के रूप में ImmutableList देखने की अनुमति है।

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

+0

कॉलिन उदाहरण के लिए धन्यवाद। इसके माध्यम से जा रहा है। – t0mcat

4

सबसे पहले, जावा-लिट में आपकी पसंद के लिए आपको कुडोस: ब्लोच की पुस्तक उत्कृष्ट प्राइमर है।

अपने दूसरे प्रश्न का उत्तर देने के लिए ('रचनाकारों के विपरीत स्थिर फैक्ट्री विधियों को हर बार एक नई वस्तु बनाने की आवश्यकता नहीं होती है'), यह जानना महत्वपूर्ण है कि ब्लॉच कह रहा है कि आपके पास एक स्थिर कारखाने के साथ विकल्प या तो: एक नई वस्तु लौटाना या पूर्व-मौजूदा एक लौटाना। यह सब उस चीज पर निर्भर करता है जो आप करना चाहते हैं।

उदाहरण के लिए, मान लीजिए कि आपके पास मनी का एक बहुत ही सरल मूल्य वर्ग है। आपकी स्थैतिक फैक्ट्री विधि को शायद एक नया उदाहरण वापस करना चाहिए - यानी, पैसे के लिए एक विशिष्ट मूल्य वाला एक नया ऑब्जेक्ट। तो, इस तरह:

public class Money { 

    private Money(String amount) { ... } /* Note the 'private'-constructor */ 

    public static Money newInstance(String amount) { 
     return new Money(amount); 
    } 

} 

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

public ResourceManager { 

    private final static ResourceManager me = new ResourceManager(); 

    private ResourceManager() { ... } /* Note the 'private'-constructor */ 

    public static ResourceManager getSingleton() { 
     return ResourceManager.me; 
    } 
} 

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


अपने पहले सवाल का जवाब करने के लिए, इस पर विचार करें (वैसे नहीं सबसे अच्छा उदाहरण, यह बहुत तदर्थ है):

public class Money { 

    private Money(String amount) { ... } 


    public static Money getLocalizedMoney(MoneyType localizedMoneyType, String amount) { 
     switch(localizedMoneyType) { 
      case MoneyType.US: 
       return new Money_US(amount); 
      case MoneyType.BR: 
       return new Money_BR(amount); 
      default: 
       return new Money_US(amount); 
     } 
    } 
} 

public class Money_US extends Money { ... } 

public class Money_BR extends Money { ... } 

नोट मैं कैसे अब यह कर सकते हैं:

Money money = Money.getLocalizedMoney(user_selected_money_type); 
saveLocalizedMoney(money); 

फिर, एक वास्तव में योगदान हुआ उदाहरण है लेकिन उम्मीद है कि इससे आपको उस बिंदु के साथ ब्लोच मिल रहा था या उससे कम या कम देखने में मदद करता है।

अन्य उत्तरों अच्छे थे - मुझे लगता है कि, शुरुआत के रूप में, कभी-कभी यह कुछ वास्तविक कोड देखने में मदद करता है।

+0

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

+0

एनपी - जब भी एक नई अवधारणा सीखती है, मैं हमेशा सार/अस्पष्ट उत्तर के साथ संघर्ष करता हूं - एक संक्षिप्त स्पष्टीकरण के साथ हार्ड-कोड आमतौर पर मेरे लिए बहुत आगे जाता है। बीटीडब्ल्यू, ब्लोच की पुस्तक में "आइटम 3" आपको सिंगलटन-फैक्ट्री दृष्टिकोण के बारे में चबाने के लिए बहुत कुछ देगा। – Bane

+0

धन्यवाद बाने। इसके लिए आगे देख रहे हैं। आप लोग मुझसे बहुत सारे प्रश्न देखने जा रहे हैं :) – t0mcat