2010-04-05 10 views
17

में एक अपरिवर्तनीय वर्ग को परिभाषित करने का सबसे अच्छा तरीका मैं उद्देश्य सी में एक नौसिखिया हूं और मैं सोच रहा था कि उद्देश्य-सी में एक अपरिवर्तनीय वर्ग को परिभाषित करने का सबसे अच्छा तरीका है (उदाहरण के लिए एनएसएसटींग की तरह)।उद्देश्य सी

मैं जानना चाहता हूं कि कक्षा को अपरिवर्तनीय बनाने के लिए मूल नियम क्या हैं।

मुझे लगता है कि:

  • setters प्रदान नहीं की जानी चाहिए
  • गुण उपयोग किया जाता है, तो वे केवल पढ़ने के लिए होना चाहिए
  • "को निष्क्रिय करने के लिए" कुंजी मान कोडिंग, accessInstanceVariablesDirectly ओवरराइड होना चाहिए और लौट नहीं

क्या मैंने कुछ भूल लिया?

धन्यवाद

उत्तर

13

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

आप निश्चित रूप से सार्वजनिक setters या ReadWrite गुण प्रदान नहीं करना चाहिए अगर आप वर्ग का इरादा अडिग होने के लिए (लेकिन निश्चित रूप से आप निजी setters ताकि आप वर्ग के भीतर accessors उपयोग कर सकते हैं प्रदान करना चाहिए, तुम हमेशा से बचने के, यहां तक ​​कि आंतरिक रूप से करना चाहिए , कुछ जगहों को छोड़कर सीधे इवर के साथ गड़बड़ाना)। मुझे लगता है कि यदि आप इसे कॉलर के हिस्से में संभावित त्रुटि के रूप में देखते हैं तो आप अपना accessInstanceVariablesDirectly ओवरराइड जोड़ सकते हैं।

लेकिन उद्देश्य-सी को समझने की कुंजी यह समझने और गले लगाने के लिए है कि कॉलर दुश्मन नहीं है। कॉल किए गए कोड को कॉलर से "संरक्षित" होने की आवश्यकता नहीं है। कॉलर को संभावित त्रुटि से संरक्षित करने की आवश्यकता है। हर कोई एक ही तरफ है; कॉलर और कहा जाता है कि कार्यक्रम काम करना चाहता है।

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

किसी भी मामले में, आपको अपर्याप्तता को लागू करने की कोशिश करने के लिए अपनी कक्षा को अत्यधिक जटिल नहीं बनाना चाहिए। कॉलर लगभग (*) सीधे स्ट्रक्चर (object->ivar) तक पहुंच करके encapsulation का उल्लंघन कर सकते हैं। कॉलर ऐसा करने के लिए मूर्ख होगा, लेकिन आप इसे रोकने की कोशिश करने के लिए और भी मूर्ख होंगे। अपरिवर्तनीयता पर ध्यान दें, अपने सेटर्स को छुपाएं और अपनी संपत्ति को केवल पढ़ने के लिए चिह्नित करें, और लगभग सभी मामलों में आपको ठीक होना चाहिए।

(*) हां, एक निजी संरचना/ऑब्जेक्ट को ivar के रूप में घोंसला करके अपने डेटा को और भी छुपाएं, लेकिन फिर कॉलर पॉइंटर अंकगणितीय के साथ डेटा को संशोधित कर सकता है, इसलिए यह अभी भी "लागू नहीं हुआ" है। हमेशा खुद से पूछें कि आप वास्तव में किस समस्या को हल करने की कोशिश कर रहे हैं।

+0

वही तर्क 'रक्षात्मक' सिंगलेट्स पर लागू होता है, मुझे लगता है? –

+2

बिल्कुल। लागू सिंगलेट्स (ओवरराइडिंग + ऑलोक विथज़ोन :) लगभग हमेशा एक गलती होती है और अच्छे से ज्यादा नुकसान करती है। एकमात्र जगह जो समझ में आती है वह है यदि आप चाहते थे * सिंगलटन प्रकृति को एक निजी कार्यान्वयन विवरण बनाना चाहते हैं। अन्यथा, आपको आम तौर पर "साझा सिंगलटन" पैटर्न का उपयोग करना चाहिए जहां कई उदाहरणों की अनुमति है, या आपको NSAssert() के साथ प्रोग्रामिंग त्रुटि में दूसरा उदाहरण बनाना चाहिए। –

+1

+1 "हर किसी के समान पक्ष" रुख के लिए +1। –

6

मेरा मानना ​​है कि वे जिस तरह से मैं पूरा होता इस हेडर फाइल करने के लिए केवल सार्वजनिक रूप से आवश्यक जानकारी शामिल है। शेष ओवरराइड एक्सपोजर को सीमित करने के लिए शेष स्रोत फ़ाइल में जायेंगे।

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

मैं बहुत पहले इस निष्कर्ष पर आया था कि आप वास्तव में उद्देश्य-सी का उपयोग नहीं कर सकते जैसे कि आप जावा, सी ++ या सी # का उपयोग करेंगे। उद्देश्य-सी बस बहुत अलग है। असल में मेरा मानना ​​है कि स्थिर बनाम गतिशील विधि प्रेषण/कॉल जैसे कठोर प्रतिमान मतभेद हैं।

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