2009-02-09 11 views
5

मान लीजिए कि मेरे पास व्यक्ति के ईमेल पते के लिए गेटर और सेटर विधियों के साथ एक व्यक्ति का प्रतिनिधित्व करने वाला ऑब्जेक्ट है। सेटर विधि परिभाषा कुछ इस तरह दिख सकता है:संरचनाओं वाले तारों से आप कैसे निपटते हैं?

setEmailAddress(String emailAddress) 
    { 
    this.emailAddress = emailAddress; 
    } 

कॉलिंग person.setEmailAddress(0), फिर, एक प्रकार त्रुटि उत्पन्न होगा, लेकिन बुला person.setEmailAddress("asdf") नहीं होगा - यहाँ तक कि "asdf" हालांकि एक मान्य ईमेल पता कोई रास्ता नहीं में है।

मेरे अनुभव में, तथाकथित तार लगभग कभी अक्षरों के मनमाने ढंग से अनुक्रम नहीं हैं, लंबाई या प्रारूप पर कोई प्रतिबंध नहीं है। यूआरआई दिमाग में आते हैं - सड़क के पते के रूप में, फ़ोन नंबर के रूप में, पहले नाम के रूप में ... आपको विचार मिलता है। फिर भी इन डेटा प्रकारों को अक्सर "केवल तार" के रूप में संग्रहीत किया जाता है।

मेरी व्यक्ति वस्तु में लौटने के बाद मैं इतना

setEmailAddress(EmailAddress emailAddress) 
    // ... 

जहां EmailAddress एक वर्ग ... जिसका निर्माता एक ईमेल पते की एक स्ट्रिंग प्रतिनिधित्व लेता है की तरह setEmailAddress() संशोधित लगता है। क्या मैंने कुछ हासिल किया है?

ठीक है, इसलिए एक ईमेल पता एक बुरा उदाहरण है। एक यूआरआई वर्ग के बारे में क्या है जो एक यूआरआई का एक कन्स्ट्रक्टर पैरामीटर के रूप में एक स्ट्रिंग प्रस्तुति लेता है, और उस यूआरआई को प्रबंधित करने के लिए विधियों को प्रदान करता है - पथ को सेट करने, क्वेरी पैरामीटर लाने आदि। स्रोत स्ट्रिंग की वैधता महत्वपूर्ण हो जाती है।

तो मैं आप सभी से पूछता हूं, आप संरचनाओं के तारों से कैसे निपटते हैं? और आप अपने इंटरफेस में अपनी संरचनात्मक अपेक्षाओं को कैसे स्पष्ट करते हैं?

धन्यवाद।

उत्तर

2

प्रोग्रामिंग की दुनिया में आपका स्वागत है!

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

उदाहरण के लिए, एक ईमेल पता सत्यापित करने की समस्या काफी मुश्किल है। नियमित अभिव्यक्ति विभिन्न लोग एक ईमेल पता स्वीकार करने की पेशकश करते हैं, उदाहरण के लिए, आमतौर पर या तो "बहुत तंग" होते हैं (सबकुछ स्वीकार नहीं करते हैं) या "बहुत ढीला" (अवैध चीजें स्वीकार करते हैं)।'रेगुलर एक्सप्रेशन "ईमेल पता"', उदाहरण के लिए के लिए The first google hit का कहना है:

नियमित अभिव्यक्ति मैं सबसे प्रतिक्रिया प्राप्त करते हैं, करने के लिए "बग" पर रिपोर्ट का उल्लेख नहीं है, एक तुम सही पर मिल जाएगा इस साइट का होम पेज: \ b [ए-जेड 0-9 ._% + -] + @ [ए-जेड 0-9 .-] +। [एजेड] {2,4} \ b रीगेक्सबड्डी के साथ इस नियमित अभिव्यक्ति का विश्लेषण करें । यह नियमित अभिव्यक्ति, I दावा, किसी भी ईमेल पते से मेल खाता है। फीडबैक के अधिकांश मुझे यह बताता है कि एक ईमेल पता दिखाकर दावा करता है कि यह रेगेक्स मेल नहीं खाता है।

तथ्य यह है कि वैध ईमेल पता क्या है या नहीं, एक जटिल समस्या है, एक ऐसा प्रोग्राम जो हल करना चाहता है या नहीं। यूआरएल की समस्या भी बदतर है, खासकर दुर्भावनापूर्ण यूआरएल की संभावना को देखते हुए।

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

मैं कहूंगा कि स्ट्रिंग्स-स्ट्रक्चर की समस्या का कोई सामान्य समाधान नहीं है। इसके बजाय, यह एक मूल समस्या है जो आपके आवेदन को डिज़ाइन करते समय सही दिखाई देती है। आपके आवेदन के लिए gathering requirements की प्रक्रिया में, आपको यह निर्धारित करना चाहिए कि एप्लिकेशन में कौन सा डेटा लगेगा और एप्लिकेशन के लिए डेटा कितना सार्थक होगा। और यह वह जगह है जहां चीजें मुश्किल हो जाती हैं, क्योंकि आप इस संभावना को देख सकते हैं कि ऐप इस तरीके से बढ़ सकता है कि आपके मालिक या ग्राहक के बारे में सोचा नहीं जा सकता है - या ऐप वास्तव में उन तरीकों से बढ़ सकता है जिनके बारे में आपने सोचा नहीं है। इस प्रकार आवेदन को थोड़ा न्यूनतम की तरह लगता है उससे थोड़ा अधिक लचीला होना चाहिए। यह भी इतना लचीला नहीं होना चाहिए कि आप नीचे फंस गए हैं।

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

इन निर्णयों को बनाना एक कला है - यहां कोई कामकाजी उत्तर नहीं है जो यहां काम करता है।

+0

मैंने मूल रूप से मोरेन्डिल के जवाब को स्वीकार किया, लेकिन कुछ विचार और पुन: पढ़ने के बाद, मैंने आपका स्वीकार करने का निर्णय लिया है। ऐसा नहीं है कि मैं मोरेन्डिल से असहमत हूं, लेकिन आपका उत्तर अधिक सामान्य, कम dogmatic है, और चर्चा के प्रकार के अनुरूप मैं उत्तेजित करने की उम्मीद कर रहा था। धन्यवाद! – Metaphile

2

शीर्षक 'validation' शीर्षक के तहत यह एक बहुत ही आम समस्या है - पाठक उपयोगकर्ता इनपुट को सत्यापित करने के कई तरीके हैं, सबसे आम Regular Expressions में से एक है।

इसके लिए आप अंतर्निहित System.Net.MailAddress कक्षा का उपयोग करने पर भी विचार कर सकते हैं, क्योंकि यह ईमेल पते के लिए सत्यापन प्रदान करता है।

1

स्ट्रिंग्स स्ट्रिंग हैं। यदि आपको अपने तारों को औसत तारों से अधिक स्मार्ट होने की आवश्यकता है तो उन्हें एक संरचनात्मक वस्तु में वर्णित करना जैसा कि आप वर्णन करते हैं, एक अच्छा विचार होगा। मैं ऐसा करने के लिए एक regex का उपयोग करेंगे।

0

अच्छा, अगर आप किसी ईमेल एड्रेस ऑब्जेक्ट के साथ कई अलग-अलग प्रकार की चीजें करना चाहते हैं, तो उन अन्य कार्रवाइयों को यह जांचना नहीं है कि यह वैध ईमेल पता है या नहीं, क्योंकि ईमेल एड्रेस ऑब्जेक्ट को वैध स्ट्रिंग होने की गारंटी है। आप कन्स्ट्रक्टर में अपवाद फेंक सकते हैं या फ़ैक्टरी विधि का उपयोग कर सकते हैं या जो भी "एक सही कार्यप्रणाली" दृष्टिकोण का उपयोग कर रहे हैं।

+0

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

+0

सही। :) हमेशा के रूप में, यह सब आपके प्रचार ब्रांड के प्रचार पर निर्भर करता है। – BobbyShaftoe

+0

* shrugs * सर्वोत्तम प्रथाओं, प्रचार; जो कुछ भी तुम इसे पुकारना करना चाहते हो। ;) लॉल –

9

"संरचना के साथ स्ट्रिंग्स" सामान्य कोड गंध का एक लक्षण हैं "Primitive Obsession"।

उपाय इन संरचनाओं के हिस्सों को मान्य या कुशलतापूर्वक कोड में डुप्लिकेशंस के लिए बारीकी से देखना है। डुप्लिकेशन के पहले संकेत पर - लेकिन पहले नहीं - एक वर्ग निकालें जो संरचना को समाहित करता है और सत्यापन और क्वेरी का पता लगाता है।

+0

+1 - बहुत ऋषि सलाह। –

+0

आह "कोड गंध" वाक्यांश नहीं है ... <- रन और छुपाएं – BobbyShaftoe

+0

हां, आप नए प्रकारों में सबसे आम आदिम-टाइप किए गए चर को लपेटकर लगभग हमेशा अपने कोड की संरचना में सुधार कर सकते हैं। –

0

व्यक्तिगत रूप से, मुझे मजबूत टाइपिंग का विचार पसंद है, इसलिए यदि मैं अभी भी ऐसी भाषाओं में काम कर रहा हूं तो मैं आपके दूसरे उदाहरण की शैली के साथ जाऊंगा।एकमात्र चीज जो मैं बदलूंगा, वह अधिक "कास्ट-जैसी" संरचना का उपयोग कर सकती है, जैसे कि EmailAddressFromString(String), जिसने एक नया EmailAddress ऑब्जेक्ट उत्पन्न किया (या स्ट्रिंग सही नहीं होने पर फिट हो गया), क्योंकि मैं थोड़ा सा हूं आवेदन हंगरी नोटेशन के एक प्रशंसक।

इस पूरी समस्या, संयोग से, बहुत अच्छी तरह से जोएल द्वारा http://www.joelonsoftware.com/articles/Wrong.html में कवर किया जाता है, तो आप रुचि रखते हैं।

1

तारों को स्वरूपित करने के लिए नियमित अभिव्यक्ति आपके मित्र हैं। हर बार जब आप उनका उपयोग करना चाहते हैं तो नियमित अभिव्यक्तियों का उपयोग करने की परेशानी से बचने के लिए आप प्रत्येक भाग को संरचना में अलग से स्टोर कर सकते हैं। जैसे

struct EMail 
{ 
    String BeforeAt = "johndoe123"; 
    String AfterAt = "gmail.com"; 
} 

Struct URL 
{ 
    String Protocol = "http"; 
    String Domain = "sub.example.com"; 
    String Path = "stuff/example.html"; 
} 
0

मैं कॉल दृढ़ता से वस्तु टाइप करने के लिए सहमत है, लेकिन उन मामलों में जहाँ आप एक स्ट्रिंग से एक वस्तु को पार्स करने के लिए कर रहे हैं, इस सवाल का जवाब आसान है: त्रुटि हैंडलिंग।

त्रुटियों को संभालने के दो सामान्य तरीके हैं: अपवाद और वापसी की स्थिति। आम तौर पर यदि आप बुरी तरह से गठित डेटा प्राप्त करने की अपेक्षा करते हैं, तो आपको एक त्रुटि संदेश वापस करना चाहिए। उन मामलों के लिए जहां इनपुट की अपेक्षा नहीं की जाती है, तो मैं अपवाद फेंक दूंगा। उदाहरण के लिए, आप '[email protected]' के बजाय 'बीओबी' जैसे बीमार गठित ईमेल पते में गुजर सकते हैं। हालांकि, शून्य मानों के लिए, आप एक अपवाद फेंक सकते हैं, क्योंकि आपको शून्य से ईमेल बनाने का प्रयास नहीं करना चाहिए।

आपके प्रश्न पर लौटने पर, मुझे लगता है कि आप किसी ऑब्जेक्ट में संरचना को एन्कोड करके कुछ हासिल करते हैं। विशेष रूप से, आपको केवल यह सत्यापित करने की आवश्यकता है कि स्ट्रिंग एक विशिष्ट स्थान पर एक विशिष्ट ईमेल पते का प्रतिनिधित्व करती है, जैसे कि कन्स्ट्रक्टर। कहीं और, आपका कोड यह मानने के लिए स्वतंत्र है कि एक ईमेल एड्रेस ऑब्जेक्ट मान्य है, और आपको 'ईमेलहेल्पर' या कुछ ऐसे नामों के साथ डोडी क्लास पर भरोसा नहीं करना है।

0

मैं व्यक्तिगत रूप से ईमेल एड्रेस स्ट्रिंग को मजबूत टाइपिंग नहीं मानता क्योंकि ईमेल एड्रेस आवश्यक है, इस मामले में।

अपना ईमेल पता आप करेंगे बनाने के लिए, अभी या बाद में, की तरह कुछ करना है:

EmailAddress(String email) 

या एक सेटर

SetEmailAddress(String email) 

दोनों ही मामलों में, आप को मान्य करना होगा ईमेल स्ट्रिंग इनपुट, जो आपको अपनी प्रारंभिक सत्यापन समस्या में वापस रखता है।

जैसा कि अन्य ने बताया, नियमित अभिव्यक्तियों का उपयोग करें।

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

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