CGFloat
,
NSString
,
NSInteger
, आदि)। डेटा प्रकारों में से प्रत्येक को अलग-अलग सत्यापन एल्गोरिदम की आवश्यकता होती है। यदि आप प्रत्येक एल्गोरिथ्म को एक ऑब्जेक्ट के रूप में एन्क्रिप्ट कर सकते हैं, तो आप डेटा की जांच करने और यह निर्धारित करने के लिए कि क्या एल्गोरिथम की आवश्यकता है, अगर-और / स्विच-केस स्टेटमेंट के समूह का उपयोग नहीं कर सकता है।
ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में, आप संबंधित एल्गोरिदम को विभिन्न वर्गों की रणनीतियों में अंतर कर सकते हैं। ऐसे मामलों में उपयोग किए जाने वाले डिज़ाइन पैटर्न को रणनीति कहा जाता है। इस अध्याय में, हम रणनीति पैटर्न की अवधारणाओं और मुख्य विशेषताओं पर चर्चा करेंगे। हम इस अध्याय में बाद में एक
UITextField
पाठ क्षेत्र
UITextField
के इनपुट को मान्य करने के लिए रणनीतियों के रूप में डेटा को मान्य करने के लिए कई वर्गों को डिज़ाइन और कार्यान्वित करेंगे।
एक रणनीति पैटर्न क्या है?
इस पैटर्न में मुख्य भूमिकाओं में से एक रणनीति वर्ग द्वारा निभाई जाती है, जो सभी समर्थित एल्गोरिदम के लिए एक सामान्य इंटरफ़ेस की घोषणा करती है। रणनीतियों के विशिष्ट वर्ग भी हैं जो रणनीति इंटरफ़ेस का उपयोग करके एल्गोरिदम को लागू करते हैं। एक संदर्भ वस्तु को एक विशिष्ट रणनीति वस्तु के उदाहरण का उपयोग करके कॉन्फ़िगर किया गया है। एक संदर्भ ऑब्जेक्ट एक विशेष रणनीति वर्ग में परिभाषित एल्गोरिथ्म को लागू करने के लिए रणनीति इंटरफ़ेस का उपयोग करता है। उनके संबंध को चित्र 191 में वर्ग आरेख में चित्रित किया गया है।

चित्र 19-1। कक्षा संरचना पैटर्न रणनीति
एक समूह या संबंधित एल्गोरिदम के पदानुक्रम,
ConcreteStrategy
क्लासेस (ए, बी और सी) के रूप में एक सामान्य
algorithmInterface
साझा
algorithmInterface
, इसलिए
Context
एक ही इंटरफ़ेस का उपयोग करके एल्गोरिदम के विभिन्न संस्करणों तक पहुंच सकता है।
नोट। रणनीति पैटर्न : एल्गोरिदम के एक परिवार को परिभाषित करता है, उनमें से प्रत्येक को एन्क्रिप्ट करता है और उन्हें विनिमेय बनाता है। रणनीति उन ग्राहकों को स्वतंत्र रूप से बदलने की अनुमति देती है जो उनका उपयोग करते हैं। *
गोफ के डिज़ाइन पैटर्न (एडिसन-वेस्ले, 1994) में दी गई प्रारंभिक परिभाषा।
एक
Context
उदाहरण रनटाइम पर विभिन्न
ConcreteStrategy
ऑब्जेक्ट्स का उपयोग करके कॉन्फ़िगर किया जा सकता है। इसे
Context
वस्तु के "इनसाइड" में बदलाव माना जा सकता है, क्योंकि अंदर से परिवर्तन होते हैं। डेकोरेटर (अध्याय 16, डेकोरेटर पैटर्न और मेरा पिछला लेख देखें), इसके विपरीत, ऑब्जेक्ट की "त्वचा" को बदलते हैं, क्योंकि संशोधनों को बाहर से डॉक किया गया है। कृपया अंतर पर अधिक विस्तृत जानकारी के लिए अध्याय 16 (पिछले लेख) में "इनसाइड" को बदलने की तुलना में किसी वस्तु की "त्वचा" बदलना "खंड" का संदर्भ लें।
मॉडल-व्यू-कंट्रोलर में रणनीति पैटर्न
मॉडल-व्यू-कंट्रोलर पैटर्न में, नियंत्रक निर्धारित करता है कि मॉडल में मौजूद डेटा को कब और कैसे प्रदर्शित किया जाए। दृश्य स्वयं जानता है कि किसी चीज़ को कैसे प्रदर्शित किया जाए, लेकिन यह नहीं जानता कि जब तक कि नियंत्रक इसे इंगित नहीं करता है। किसी अन्य नियंत्रक के साथ काम करते समय, लेकिन एक ही फॉर्म के साथ, आउटपुट डेटा का प्रारूप समान हो सकता है, लेकिन नए नियंत्रक के अन्य निष्कर्षों के अनुसार डेटा प्रकार भिन्न हो सकते हैं। इस मामले में नियंत्रक, जैसा कि यह था, एक दृश्य वस्तु के लिए एक रणनीति। जैसा कि हमने पिछले अध्यायों में उल्लेख किया है, नियंत्रक और दृश्य के बीच संबंध रणनीति पैटर्न पर आधारित है।
रणनीति पैटर्न का उपयोग कब उचित है?
इस पैटर्न का उपयोग निम्नलिखित मामलों में उचित है:
- वर्ग तर्क वांछित व्यवहार का चयन करने के लिए कई सशर्त बयानों का उपयोग करता है। आप सशर्त कोड को एक अलग रणनीति वर्ग में स्थानांतरित कर सकते हैं।
- आपको एल्गोरिथ्म के विभिन्न संस्करणों की आवश्यकता है।
- आप जटिल और संकीर्ण विशिष्ट डेटा संरचनाओं (ग्राहकों के लिए) को उजागर नहीं करना चाहेंगे।
UITextField वर्ग का उपयोग करके डेटा सत्यापन रणनीतियों का उपयोग करना
आइए आवेदन में रणनीति पैटर्न के कार्यान्वयन का एक सरल उदाहरण बनाएं। मान लें कि हमें अपने आवेदन में कुछ
UITextField
ऑब्जेक्ट की आवश्यकता है जो उपयोगकर्ता इनपुट को स्वीकार करता है; हम बाद में अपने आवेदन में इनपुट परिणामों का उपयोग करेंगे। हमारे पास एक टेक्स्ट इनपुट फ़ील्ड है जो केवल अक्षरों को स्वीकार करता है, वह है, - a - z या A - Z, और इसके अलावा हमारे पास एक फ़ील्ड है जो केवल संख्यात्मक डेटा को स्वीकार करता है, वह है, 0–9। यह सुनिश्चित करने के लिए कि फ़ील्ड में इनपुट सही है, उनमें से प्रत्येक को उपयोगकर्ता के संपादन समाप्त करने के बाद किसी तरह की ऑन-साइट डेटा सत्यापन प्रक्रिया शुरू करने की आवश्यकता है।
हम आवश्यक डेटा सत्यापन को प्रतिनिधि ऑब्जेक्ट विधि
UITextField
,
textFieldDidEndEditing:
में डाल सकते हैं
textFieldDidEndEditing:
एक
UITextField
उदाहरण इस विधि को हर बार फोकस खो देता है। इस पद्धति में, हम यह सुनिश्चित कर सकते हैं कि डिजिटल क्षेत्र में केवल संख्याएं दर्ज की गई हैं, और केवल अक्षर अल्फाबेटिक क्षेत्र में दर्ज किए गए हैं। यह विधि इनपुट क्षेत्र की वर्तमान वस्तु (
textField
पैरामीटर के रूप में) के इनपुट पर एक लिंक स्वीकार करती है, लेकिन यह दो वस्तुओं में से कौन सी है?
ट्रेजिया पैटर्न के बिना, हम एक कोड में आए होंगे जैसे कि लिस्टिंग 19-1 में दिखाया गया है।
लिस्टिंग 19–1। विशिष्ट UITextField सामग्री डेलिगेशन स्क्रिप्ट को प्रतिनिधि विधि टेक्स्टFieldDidEndEditing में
- (void)textFieldDidEndEditing:(UITextField *)textField { if (textField == numericTextField) { // [textField text] , // } else if (textField == alphaTextField) { // [textField text] , // } }
बेशक, अलग-अलग डेटा के लिए अधिक इनपुट फ़ील्ड होने पर अधिक सशर्त बयान हो सकते हैं। यदि हम इन सभी सशर्त अभिव्यक्तियों से छुटकारा पा लेते हैं, तो हम कोड को अधिक प्रबंधनीय बना सकते हैं, जो भविष्य में कोड के समर्थन से हमारे जीवन को सरल बना सकते हैं।
युक्ति: यदि आपके कोड में बहुत सारे सशर्त वक्तव्य हैं, तो इसका मतलब यह हो सकता है कि आपको उन्हें फिर से बनाने और रणनीति की अलग-अलग वस्तुओं में अलग करने की आवश्यकता है।
अब हमारा लक्ष्य इस सत्यापन कोड को लेना है और इसे रणनीतियों के विभिन्न वर्गों में बिखेरना है ताकि प्रतिनिधि और अन्य तरीकों से इसका पुन: उपयोग किया जा सके। हमारी प्रत्येक कक्षा इनपुट फ़ील्ड से एक पंक्ति लेती है, फिर वांछित रणनीति के आधार पर इसे जांचती है, और अंत में
BOOL
का मान लौटाती है और चेक विफल होने पर
NSError
का एक उदाहरण देता है। लौटा हुआ
NSError
ऑब्जेक्ट यह निर्धारित करने में मदद करेगा कि सत्यापन सफल क्यों नहीं हुआ। चूंकि डिजिटल और अक्षर दोनों इनपुट का सत्यापन एक-दूसरे से संबंधित है (उनके पास एक ही प्रकार के इनपुट और आउटपुट हैं), उन्हें एक इंटरफ़ेस से जोड़ा जा सकता है। कक्षाओं का हमारा सेट चित्र 19-2 में कक्षा आरेख में दिखाया गया है।

चित्र 19–2। वर्ग आरेख CustomTextField और उससे जुड़ी रणनीतियों के बीच संबंध को दर्शाता है।
हम इस इंटरफ़ेस को एक प्रोटोकॉल के रूप में नहीं, बल्कि एक सार आधार वर्ग के रूप में घोषित करेंगे। इस मामले में अमूर्त आधार वर्ग अधिक सुविधाजनक है, क्योंकि यह सभी ठोस वर्गों की रणनीतियों के लिए व्यवहार को फिर से परिभाषित करना आसान है। हमारा सार आधार वर्ग लिस्टिंग 19-2 की तरह दिखेगा।
लिस्टिंग 19–2। InputValidator.h में एक InputValidator वर्ग की घोषणा
@interface InputValidator : NSObject { } // - (BOOL) validateInput:(UITextField *)input error:(NSError **) error; @end
UITextField
validateInput: error:
विधि एक इनपुट पैरामीटर के रूप में
UITextField
संदर्भ को स्वीकार करता है, इसलिए यह इनपुट क्षेत्र में सब कुछ जांच सकता है और चेक के परिणामस्वरूप
BOOL
मान लौटाता है। विधि एक
NSError
को पॉइंटर के संदर्भ को भी स्वीकार करती है। जब किसी प्रकार की त्रुटि हुई (अर्थात, विधि इनपुट की शुद्धता को सत्यापित नहीं कर सकी), तो विधि
NSError
का एक उदाहरण बनाएगी और इसे पॉइंटर को असाइन करेगी, इसलिए, जिस भी संदर्भ में सत्यापन वर्ग का उपयोग किया जाता है, इस ऑब्जेक्ट से त्रुटि के बारे में अधिक विस्तृत जानकारी प्राप्त करना हमेशा संभव होता है।
इस पद्धति का डिफ़ॉल्ट कार्यान्वयन केवल त्रुटि सूचक को
nil
सेट करता है और
NO
वापस करता है, जैसा कि 19-3 लिस्टिंग में दिखाया गया है।
लिस्टिंग 19-3। InputValidator.m में InputValidator वर्ग का डिफ़ॉल्ट कार्यान्वयन
#import "InputValidator.h" @implementation InputValidator // - (BOOL) validateInput:(UITextField *)input error:(NSError **) error { if (error) { *error = nil; } return NO; } @end
हमने इनपुट पैरामीटर के रूप में
NSString
उपयोग क्यों नहीं किया? इस मामले में, रणनीति ऑब्जेक्ट के अंदर कोई भी कार्रवाई एकतरफा होगी। इसका अर्थ है कि सत्यापनकर्ता केवल एक चेक करेगा और मूल मूल्य को संशोधित किए बिना परिणाम लौटाएगा।
UITextField
प्रकार के इनपुट पैरामीटर के साथ
UITextField
हम दो दृष्टिकोणों को जोड़ सकते हैं। हमारी स्कैन ऑब्जेक्ट टेक्स्ट फ़ील्ड के प्रारंभिक मूल्य (उदाहरण के लिए, गलत वर्णों को हटाकर) को बदलने में सक्षम होगी या इसे बदलने के बिना केवल मूल्य देख सकती है।
एक और सवाल यह है कि अगर चेक फेल हो जाता है तो हम सिर्फ
NSException
क्यों नहीं फेंकते? ऐसा इसलिए है क्योंकि अपने स्वयं के अपवाद को फेंकना और कोको टच फ्रेम में एक कोशिश-कैच ब्लॉक में इसे पकड़ना एक बहुत ही संसाधन-गहन ऑपरेशन है और अनुशंसित नहीं है (लेकिन कोशिश-कैच सिस्टम अपवाद एक पूरी तरह से अलग मामला है)। कोको टच डेवलपर गाइड में सिफारिश की गई
NSError
वस्तु को वापस करना अपेक्षाकृत सस्ता है। यदि हम कोकोआ टच फ्रेमवर्क प्रलेखन को देखते हैं, तो हम देखेंगे कि कई एपीआई ऐसे हैं जो कुछ असामान्य स्थिति होने पर
NSError
उदाहरण देते हैं। एक सामान्य उदाहरण
NSFileManager
विधियों में से एक है,
(BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error
। यदि
NSFileManager
फ़ाइल को एक स्थान से दूसरे स्थान पर ले जाने का प्रयास करता है, तो एक त्रुटि होती है, यह एक नया
NSError
उदाहरण बनाएगा जो समस्या का वर्णन करता है। कॉलिंग विधि त्रुटियों को आगे संभालने के लिए लौटे
NSError
ऑब्जेक्ट में निहित जानकारी का उपयोग कर सकती है। इस प्रकार, हमारी विधि में
NSError
ऑब्जेक्ट का लक्ष्य काम के इनकार के बारे में जानकारी प्रदान करना है।
अब हमने परिभाषित किया है कि एक अच्छे इनपुट सत्यापन वर्ग को कैसे व्यवहार करना चाहिए। अब हम एक वास्तविक समीक्षक बनाना शुरू कर सकते हैं। आइए पहले इनपुट नंबर के लिए एक बनाएं, जैसा कि लिस्टिंग 19-4 में दिखाया गया है।
लिस्टिंग 19-4। NumericInputValidator.h में एक NumericInputValidator वर्ग की घोषणा करना
#import "InputValidator.h" @interface NumericInputValidator : InputValidator { } // , , // , 0-9 - (BOOL) validateInput:(UITextField *)input error:(NSError **) error; @end
NumericInputValidator
अमूर्त आधार वर्ग
NumericInputValidator
विरासत में मिला है और इसकी
NumericInputValidator
को ओवरराइड करता है
validateInput: error:
विधि। हम इस उपवर्ग को लागू करने या फिर से परिभाषित करने पर जोर देने के लिए फिर से विधि की घोषणा करते हैं। यह आवश्यक नहीं है, लेकिन अच्छा अभ्यास है।
विधि का कार्यान्वयन 19-5 की सूची में दिखाया गया है।
लिस्टिंग 19-5। NumericInputValidator.m में NumericInputValidator वर्ग का कार्यान्वयन
#import "NumericInputValidator.h" @implementation NumericInputValidator - (BOOL) validateInput:(UITextField *)input error:(NSError**) error { NSError *regError = nil; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]*$" options:NSRegularExpressionAnchorsMatchLines error:®Error]; NSUInteger numberOfMatches = [regex numberOfMatchesInString:[input text] options:NSMatchingAnchored range:NSMakeRange(0, [[input text] length])]; // , // NO if (numberOfMatches == 0) { if (error != nil) { NSString *description = NSLocalizedString(@"Input Validation Failed", @""); NSString *reason = NSLocalizedString(@"The input can contain only numerical values", @""); NSArray *objArray = [NSArray arrayWithObjects:description, reason, nil]; NSArray *keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey, NSLocalizedFailureReasonErrorKey, nil]; NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:objArray forKeys:keyArray]; *error = [NSError errorWithDomain:InputValidationErrorDomain code:1001 userInfo:userInfo]; } return NO; } return YES; } @end
validateInput:error:
का कार्यान्वयन
validateInput:error:
विधि मुख्य रूप से दो पहलुओं पर केंद्रित है:
- यह पहले बनाए गए
NSRegularExpression
ऑब्जेक्ट के साथ इनपुट फ़ील्ड में संख्यात्मक डेटा के मैचों की संख्या की जांच करता है। हमारे द्वारा उपयोग की जाने वाली नियमित अभिव्यक्ति "^ [0–9] * $" है। इसका अर्थ है कि संपूर्ण पंक्ति की शुरुआत से ("^" द्वारा इंगित) और अंत ("$" द्वारा दर्शाया गया है), सेट से 0 या अधिक वर्ण ("*" द्वारा) होना चाहिए जिसमें केवल अंक ("0/9) द्वारा इंगित किया गया हो। ")। - यदि कोई मेल नहीं हैं, तो वह एक नया
NSError
ऑब्जेक्ट बनाता है जिसमें संदेश "इनपुट में केवल संख्यात्मक मान हो सकते हैं" और इसेNSError
एक इनपुट पॉइंटर को असाइन करता है। फिर यह अंततः प्रकारBOOL
का मान लौटाता है जो ऑपरेशन की सफलता या विफलता का संकेत देता है। त्रुटि विशेष कोड 1001 के साथ जुड़ी हुई है औरInputValidator
वर्ग के हेडर फाइल में परिभाषित त्रुटि डोमेन के विशेष मूल्य के रूप में नीचे दिखाया गया है:
static NSString * const InputValidationErrorDomain = @"InputValidationErrorDomain";
NumericInputValidator
वर्ग का भाई, जो इनपुट में केवल अक्षरों की जांच करता है, जिसे
AlphaInputValidator
कहा जाता है, में इनपुट फ़ील्ड की सामग्री की जाँच के लिए एक समान एल्गोरिथ्म होता है।
AlphaInputValidator
के समान विधि को ओवरराइड करता है। जाहिर है, यह एल्गोरिथ्म पुष्टि करता है कि इनपुट स्ट्रिंग में केवल अक्षर होते हैं, जैसा कि लिस्टिंग 19-6 में दिखाया गया है।
लिस्टिंग 19-6। AlphaInputValidator.m में AlphaInputValidator वर्ग का कार्यान्वयन
#import "AlphaInputValidator.h" @implementation AlphaInputValidator - (BOOL) validateInput:(UITextField *)input error:(NSError**) error { NSError *regError = nil; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z]*$" options:NSRegularExpressionAnchorsMatchLines error:®Error]; NSUInteger numberOfMatches = [regex numberOfMatchesInString:[input text] options:NSMatchingAnchored range:NSMakeRange(0, [[input text] length])]; // , // NO if (numberOfMatches == 0) { if (error != nil) { NSString *description = NSLocalizedString(@"Input Validation Failed", @""); NSString *reason = NSLocalizedString(@"The input can contain only letters", @""); NSArray *objArray = [NSArray arrayWithObjects:description, reason, nil]; NSArray *keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey, NSLocalizedFailureReasonErrorKey, nil]; NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:objArray forKeys:keyArray]; *error = [NSError errorWithDomain:InputValidationErrorDomain code:1002 userInfo:userInfo]; } return NO; } return YES; } @end
हमारा
AlphaInputValidator
वर्ग भी
AlphaInputValidator
एक प्रकार
AlphaInputValidator
और
AlphaInputValidator
विधि
validateInput:
लागू करता है। इसके पास एक भाई-जैसा,
NumericInputValidator
, कोड संरचना और एल्गोरिदम है, सिवाय इसके कि यह
NSRegularExpression
ऑब्जेक्ट में एक अलग नियमित अभिव्यक्ति का उपयोग करता है, और त्रुटि कोड और संदेश पत्र सत्यापन के लिए विशिष्ट हैं। नियमित अभिव्यक्ति जो हम अक्षरों का परीक्षण करने के लिए उपयोग करते हैं, "^ [a-zA-Z] * $" है। यह उनके साथी संख्यात्मक सत्यापन के लिए एक अभिव्यक्ति की तरह दिखता है, सिवाय इसके कि वैध वर्णों के सेट में निचले और ऊपरी दोनों प्रकार के अक्षर होते हैं। जैसा कि हम देख सकते हैं, दोनों संस्करणों में बहुत सारे डुप्लिकेट कोड हैं। दोनों एल्गोरिदम में एक समान संरचना है; आप एक टेंपलेट विधि (अध्याय 18 देखें) को एक सार आधार वर्ग में संरचना को रिफ्लेक्टर कर सकते हैं।
InputValidator
विशिष्ट उपवर्ग
InputValidator
एल्गोरिथ्म में अद्वितीय जानकारी वापस करने के लिए
InputValidator
में परिभाषित आदिम परिचालनों को ओवरराइड कर सकते हैं - उदाहरण के लिए,
NSError
ऑब्जेक्ट की नियमित अभिव्यक्ति और विभिन्न निर्माण विशेषताएँ, आदि। मैं इसे आपको एक अभ्यास के रूप में छोड़ दूँगा।
अब हमारे पास पहले से ही सत्यापन कक्षाएं हैं जो आवेदन में उपयोग के लिए तैयार हैं। हालांकि,
UITextFiel
d उनके बारे में नहीं जानता है, इसलिए हमें
UITextField
अपने संस्करण की आवश्यकता है, जो सब कुछ समझता है। हम
UITextField
का एक उपवर्ग बनाएंगे जिसमें
InputValidator
और
validate
विधि का संदर्भ होता है, जैसा कि लिस्टिंग 19-7 में दिखाया गया है।
लिस्टिंग 19-7। CustomTextField वर्ग की घोषणा CustomTextField.h में
#import "InputValidator.h" @interface CustomTextField : UITextField { @private InputValidator *inputValidator_; } @property (nonatomic, retain) IBOutlet InputValidator *inputValidator; - (BOOL) validate; @end
CustomTextField
में एक ऐसी संपत्ति होती है जो
InputValidator
संदर्भ रखती है। जब इसकी
validate
विधि को बुलाया जाता है, तो यह सत्यापन शुरू करने के लिए
InputValidator
संदर्भ का उपयोग करता है। हम इसे 198 की लिस्टिंग में दिखाए गए कार्यान्वयन में देख सकते हैं।
लिस्टिंग 19-8। CustomTextField.m में CustomTextField वर्ग कार्यान्वयन
#import "CustomTextField.h" @implementation CustomTextField @synthesize inputValidator=inputValidator_; - (BOOL) validate { NSError *error = nil; BOOL validationResult = [inputValidator_ validateInput:self error:&error]; if (!validationResult) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[error localizedDescription] message:[error localizedFailureReason] delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil]; [alertView show]; [alertView release]; } return validationResult; } - (void) dealloc { [inputValidator_ release]; [super dealloc]; } @end
संदेश
[inputValidator_ validateInput:self
error:&error]
validate
विधि में भेजा गया है
[inputValidator_ validateInput:self
error:&error]
[inputValidator_ validateInput:self
error:&error]
लिंक
inputValidator_
। पैटर्न की सुंदरता यह है कि
CustomTextField
को यह जानने की आवश्यकता नहीं है कि यह किस प्रकार के
InputValidator
का उपयोग करता है या एल्गोरिथ्म का कोई विवरण। इसलिए, यदि भविष्य में हम कुछ नए
InputValidator
जोड़ते हैं, तो
CustomTextField
ऑब्जेक्ट उसी तरह से नए
InputValidator
उपयोग करेगा।
लिहाजा, पूरी तैयारी की गई है। मान लीजिए कि क्लाइंट एक
UIViewController
है जो
UITextFieldDelegate
प्रोटोकॉल को लागू करता है और इसमें
CustomTextField
प्रकार के दो
IBOutlets
शामिल हैं, जैसा कि लिस्टिंग 19-9 में दिखाया गया है।
लिस्टिंग 19-9। StrategyViewController.h में StrategyViewController वर्ग घोषणा
#import "NumericInputValidator.h" #import "AlphaInputValidator.h" #import "CustomTextField.h" @interface StrategyViewController : UIViewController <UITextFieldDelegate> { @private CustomTextField *numericTextField_; CustomTextField *alphaTextField_; } @property (nonatomic, retain) IBOutlet CustomTextField *numericTextField; @property (nonatomic, retain) IBOutlet CustomTextField *alphaTextField; @end
हमने नियंत्रक प्रतिनिधि विधि
(void)textFieldDidEndEditing:(UITextField *)textField
लागू करने का निर्णय लिया।
(void)textFieldDidEndEditing:(UITextField *)textField
और वहाँ जाँच डालें। इस क्षेत्र को हर बार इनपुट क्षेत्र में मूल्य में परिवर्तन कहा जाएगा और फोकस खो जाएगा। जब उपयोगकर्ता टाइप करना समाप्त कर देता है, तो हमारा
CustomTextField
वर्ग इस प्रतिनिधि पद्धति को कॉल करेगा, जैसा कि सूची 19-10 में दिखाया गया है।
लिस्टिंग 19-10। प्रतिनिधि कोड टेक्स्ट में ग्राहक कोड परिभाषित किया गया है ।FieldDidEndEditing :, जो एक रणनीति ऑब्जेक्ट (InputValidator) का उपयोग करके CustomTextField के एक उदाहरण को मान्य करता है
@implementation StrategyViewController @synthesize numericTextField, alphaTextField; // ... // // ... #pragma mark - #pragma mark UITextFieldDelegate methods - (void)textFieldDidEndEditing:(UITextField *)textField { if ([textField isKindOfClass:[CustomTextField class]]) { [(CustomTextField*)textField validate]; } } @end
textFieldDidEndEditing:
कॉल करते समय
textFieldDidEndEditing:
जब खेतों में से किसी एक में संपादन पूरा हो जाता है, तो विधि यह
textField
कि
textField
ऑब्जेक्ट
CustomTextField
वर्ग का है। यदि ऐसा है, तो वह प्रवेश किए गए पाठ की जांच की प्रक्रिया शुरू करने के लिए उसे एक
validate
संदेश भेजता है। जैसा कि हम देख सकते हैं, हमें अब इन सशर्त बयानों की आवश्यकता नहीं है। इसके बजाय, हमारे पास समान उद्देश्य के लिए बहुत सरल कोड है। अतिरिक्त जाँच के अपवाद के साथ कि
textField
एक
CustomTextField
, अधिक जटिल कुछ भी नहीं है।
लेकिन एक पल रुकिए। कुछ बहुत अच्छा नहीं लगता है। हम कैसे कर सकते हैं सही
InputValidator numericTextField_
इंस्टेंसेस के
InputValidator numericTextField_
और
alphaTextField_
को
StrategyViewController
में परिभाषित? दोनों इनपुट फील्ड्स को
IBOutlet
को Listing 199 में घोषित किया गया है। हम उन्हें इंटरफ़ेस बिल्डर व्यू कंट्रोलर में
IBOutlet
माध्यम से चुन सकते हैं, जैसा कि हम अन्य बटन और बहुत कुछ के साथ करते हैं। इसी तरह, लिस्टिंग
inputValidator
में
CustomTextField
वर्ग की घोषणा में, इसकी
inputValidator
संपत्ति एक
IBOutlet
भी है, जिसका अर्थ है कि हम
inputValidator
एक उदाहरण इंटरफ़ेस इंटरफ़ेस में एक
*TextField
ऑब्जेक्ट को भी असाइन कर सकते हैं।इस प्रकार, सब कुछ इंटरफ़ेस बिल्डर संदर्भ लिंक का उपयोग करके निर्माण किया जा सकता है यदि आप कुछ वर्ग गुणों को घोषित करते हैं
IBOutlet
। कस्टम इंटरफ़ेस बिल्डर ऑब्जेक्ट्स का उपयोग करने के तरीके के बारे में अधिक विस्तृत चर्चा के लिए,
CoordinatingController
अध्याय 11 में "इंटरफ़ेस बिल्डर का उपयोग करना" देखें , जो मध्यस्थ पैटर्न के बारे में बात करता है।
निष्कर्ष
इस अध्याय में, हमने रणनीति पैटर्न की अवधारणाओं और विभिन्न संबंधित एल्गोरिदम का उपयोग करने के लिए ग्राहकों के लिए इस पैटर्न का उपयोग करने के तरीके पर चर्चा की। एक कस्टम एक के लिए इनपुट जांच के कार्यान्वयन का एक उदाहरण
UITextField
दिखाता है कि चेक के विभिन्न वर्ग किसी वस्तु के "आंतरिक" को कैसे बदल सकते हैं। रणनीति पैटर्न कुछ हद तक डेकोरेटर पैटर्न (अध्याय 16 और मेरे पिछले लेख) के समान है। सज्जाकार बाहर से किसी वस्तु के व्यवहार का विस्तार करते हैं जबकि विभिन्न रणनीतियों को वस्तु के भीतर समझाया जाता है। जैसा कि वे कहते हैं, सज्जाकार वस्तु की "त्वचा" को बदलते हैं, और रणनीतियों - "अंदरूनी"।
अगले अध्याय में, हम एक और पैटर्न देखेंगे, जो एल्गोरिदम के एनकैप्सुलेशन से भी जुड़ा हुआ है। एन्कैप्सुलेटेड एल्गोरिथ्म का उपयोग मुख्य रूप से एक अलग ऑब्जेक्ट के रूप में कमांड के निष्पादन को स्थगित करने के लिए किया जाता है।