2015-11-19 9 views
15

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में सार्वजनिक क्षेत्रों का उपयोग करने के बारे में कई प्रश्न और उत्तर हैं, और उनमें से अधिकतर कई कारणों से सार्वजनिक क्षेत्रों का उपयोग न करने की सलाह देते हैं।कुछ एंड्रॉइड कोड में सार्वजनिक फ़ील्ड क्यों हैं?

लेकिन जब मैंने एंड्रॉइड के कोड में देखा तो मुझे पता चला कि कुछ वर्ग सार्वजनिक क्षेत्रों का उपयोग कर रहे हैं। उदाहरण के लिए Android.view.View में सार्वजनिक फ़ील्ड mCachingFailed और mAttributes हैं।

वे सार्वजनिक क्यों हैं? यह सोचना मुश्किल है कि यह Google और एओएसपी के हिस्से पर एक गलती है।

+0

आप हमसे क्यों पूछ रहे हैं? लेखकों से पूछो। वे क्नोव्स। – EJP

+2

@EJP उन्होंने कहा कि उन्होंने जानबूझकर एंड्रॉइड इश्यू ट्रैकर में किया था। (उन्होंने निजी के बजाय सार्वजनिक + '@ hide' का उपयोग किया) मेरे पास एंड्रॉइड डेवलपर्स के लिए कोई व्यक्तिगत संपर्क नहीं है, और मुझे लगता है कि एंड्रॉइड इश्यू ट्रैकर क्यू एंड ए के लिए नहीं है। –

+0

प्रदर्शन कारणों की अधिक संभावना है, यानी अन्य पैकेजों से कक्षाओं को कुछ महत्वपूर्ण पथों पर पहुंचने की आवश्यकता है। दरअसल 'android.widget.ListView' इसे 'DrawChild (कैनवास कैनवास, देखें बच्चे, लंबे ड्राइंगटाइम) में संदर्भित करता है। लेकिन आधिकारिक आंकड़ों से कोई टिप्पणी के बिना यह सिर्फ एक अनुमान है। – Kai

उत्तर

13

यह सार्वजनिक रूप से सार्वजनिक फ़ील्ड रखने की गलती नहीं है। ऐसा नहीं है, क्योंकि बक्षीस नोट सुझाव देता है, "ओओपी-मौलिक उल्लंघन"। इन सभी को दो वर्गों (सबसे प्रयोजनों के लिए) समान हैं के बाद:

public class DemoA { 
    public int field; 
} 

public class DemoB { 
    private int field; 

    public int getField() { return field; } 
    public void setField(int value) { field = value; } 
} 

है, कहने के लिए अगर आप इरादा कॉल प्रत्यक्ष पढ़ने के लिए के लिए और एक गेटर जोड़ने एक क्षेत्र के लिए उपयोग लिखने और सेटर बस हो सकता है अतिरिक्त बॉयलर प्लेट।

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

हालांकि कभी-कभी यह केवल ओवरकिल होता है, और सार्वजनिक कॉलकों का खुलासा करना बिल्कुल उचित है यदि आपके कॉलर्स की आवश्यकता को प्रदान करने का यह सबसे अच्छा तरीका है। अक्सर, यह value types के लिए किया जाता है, जो कक्षाएं मौजूद हैं, केवल एक साथ कई फ़ील्ड समूह करने के लिए। गेटर्स और सेटर्स के स्कोर लिखने के लिए बहुत कम लाभ होता है जब आपको कक्षा बनाने की ज़रूरत होती है, केवल फ़ील्ड को सार्वजनिक करके पूरा किया जा सकता है।

एक व्यावहारिक मामले के रूप में, एंड्रॉइड की एक अतिरिक्त चिंता है। विधि कॉल महंगे हैं और ऐप (आसानी से) परिभाषित करने की विधियों की संख्या limited to ~65k है। ऐसे मामलों के लिए जहां ऐसा करना सुरक्षित है, एक क्षेत्र को उजागर करने से विधि को ओवरहेड दो से कम कर देता है और मूल्यवान CPU समय बचाता है। यह बहुत कुछ प्रतीत नहीं होता है, लेकिन यह जल्दी से जोड़ता है। developer.android.com से इस खंड

+0

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

+0

निश्चित रूप से, यह संभावित रूप से मामूली तेजी से है। लेकिन कंपाइलर और जेआईटी दोनों संभावित रूप से क्षेत्रीय पहुंच के लिए गेटर्स/सेटर्स को अनुकूलित कर सकते हैं, इसलिए यह संभवतः बहुत सीमित ओवरहेड है। हालांकि, इस बिंदु पर अधिक, आपको दक्षता के कारणों के लिए डिज़ाइन निर्णय लेने से बचना चाहिए जब तक कि आप निश्चित न हों कि यह एक बाधा है। दक्षता के नाम पर खराब कोड लिखने की लागत मामूली अक्षमता की लागत से काफी अधिक है जो कभी-कभी अच्छे पैटर्न के साथ आती है। – dimo414

+0

@mad_manny मुझे लगता है कि यह वही है जो आप पढ़ते हैं: http://developer.android.com/training/articles/perf-tips.html#GettersSetters "सामान्य ऑब्जेक्ट उन्मुख प्रोग्रामिंग प्रथाओं का पालन करना उचित है और इसमें गेटर्स और सेटर्स हैं सार्वजनिक इंटरफ़ेस, लेकिन एक कक्षा के भीतर आपको हमेशा फ़ील्ड तक पहुंचना चाहिए। " –

6

चेक आउट:

सी की तरह देशी भाषाओं ++ में यह ही टिककर खेल का उपयोग करने के आम बात है (i = getCount()) के बजाय सीधे क्षेत्र तक पहुँचने (i = mCount)। यह सी ++ के लिए एक उत्कृष्ट आदत है और अक्सर अन्य ऑब्जेक्ट सी # और जावा जैसी उन्मुख भाषाओं में अभ्यास किया जाता है, क्योंकि संकलक आमतौर पर एक्सेस इनलाइन कर सकते हैं, और यदि आपको फ़ील्ड एक्सेस को प्रतिबंधित या डिबग करने की आवश्यकता है तो आप कोड जोड़ सकते हैं किसी भी समय।

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

एक जेआईटी के बिना, त्रिभुज गेटर का आह्वान करने से प्रत्यक्ष क्षेत्र का उपयोग लगभग 3x तेज है। जेआईटी के साथ (जहां प्रत्यक्ष क्षेत्र का उपयोग स्थानीय के रूप में सस्ता है), प्रत्यक्ष क्षेत्र का उपयोग से लगभग 7x तेज है जो एक छोटे से गेटर का आह्वान करता है।

नोट आप ProGuard उपयोग कर रहे हैं, तो आप दोनों दुनिया का सबसे अच्छा हो सकता है क्योंकि ProGuard के लिए आप

http://developer.android.com/training/articles/perf-tips.html#GettersSetters

सबसे अधिक संभावना accessors इनलाइन कर सकते हैं, इस कारण से आप सार्वजनिक देखें एओएसपी में खेतों।

+0

यह जानना बहुत अच्छा है कि आधिकारिक एंड्रॉइड डेवलपर वेबसाइट में इसका उल्लेख किया गया था। हालांकि, हमें यह ध्यान रखना होगा कि वेबपृष्ठ "आंतरिक" गेटर्स/सेटर्स से परहेज करने के बारे में है, और कक्षा के बाहर से सीधे सार्वजनिक क्षेत्र तक पहुंचने की वैधता के बारे में कुछ भी नहीं बता रहा है। (यह भी देखें: http://stackoverflow.com/questions/6716442/android-performance-avoid-internal-getters-setters) – Taka

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