अपने मॉडल में "FullName" या "FormattedPhoneNumber" जैसे गेटर्स लगाना "पैटर्न गंध" है?


13

मैं एक ASP.NET MVC ऐप पर काम कर रहा हूं, और मुझे अपने मॉडल / यूनिट कक्षाओं में सहायक और सुविधाजनक गेटर्स की तरह लगने की आदत पड़ रही है।

उदाहरण के लिए:

public class Member
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }

    public string FormattedPhoneNumber
    {
        get { return "(" + PhoneNumber.Substring(0, 3) + ") " + PhoneNumber.Substring(3, 3) + "-" + PhoneNumber.Substring(6); }
    }
}

मुझे आश्चर्य है कि लोग FullNameऔर FormattedPhoneNumberपाने वालों के बारे में सोचते हैं ।

वे पूरे ऐप में मानकीकृत डेटा प्रारूप तैयार करना बहुत आसान बनाते हैं, और वे बहुत बार-बार कोड को सहेजते प्रतीत होते हैं, लेकिन यह निश्चित रूप से तर्क दिया जा सकता है कि डेटा प्रारूप कुछ ऐसा है जिसे मॉडल से व्यू-मॉडल में मैपिंग में संभाला जाना चाहिए।

वास्तव में, मैं मूल रूप से इन डेटा प्रारूपों को अपनी सेवा परत में लागू कर रहा था, जहां मैं अपनी मैपिंग करता हूं, लेकिन यह लगातार एक फॉर्मेटर्स लिखने के लिए उन्हें कई अलग-अलग जगहों पर लागू करने के लिए बोझ बन रहा था। उदाहरण के लिए, मैं अधिकांश दृश्यों में "पूर्ण नाम" का उपयोग करता हूं, और model.FullName = MappingUtilities.GetFullName(entity.FirstName, entity.LastName);सभी जगह कुछ टाइप करने के लिए बस टाइपिंग की तुलना में बहुत कम सुरुचिपूर्ण लग रहा था model.FullName = entity.FullName(या, यदि आप ऑटोमैपर जैसी किसी चीज का उपयोग करते हैं, तो संभवतः कुछ भी टाइप नहीं कर रहे हैं)।

तो, डेटा स्वरूपण की बात करते समय आप कहां रेखा खींचते हैं। क्या आपके मॉडल में डेटा स्वरूपण करना "ठीक है" या "पैटर्न गंध" है?

नोट: मेरे मॉडल में निश्चित रूप से कोई html नहीं है। मैं उसके लिए html हेल्पर्स का उपयोग करता हूं। मैं सख्ती से स्वरूपण या डेटा के संयोजन (और विशेष रूप से अक्सर उपयोग किए जाने वाले डेटा) के बारे में बात कर रहा हूं।


1
ऐसा करना सुविधाजनक हो सकता है। लेकिन आशा और प्रार्थना करें कि आपको कभी भी उस कोड का अंतर्राष्ट्रीयकरण नहीं करना पड़ेगा।
btilly

@btilly, अच्छी बात है, लेकिन मैं लगभग 99.99% आश्वस्त हूं कि मैं नहीं करूंगा।
देवकर

FullName और PhoneNumber के लिए विशिष्ट, निश्चित रूप से। क्या विशेष रूप से उन लोगों के बारे में सवाल है, क्योंकि उनके पास विभिन्न संस्कृतियों में असंगत प्रारूप हैं, या @DanM ने ​​केवल ऐसे उदाहरण उठाए हैं जो अधिक सामान्य प्रश्न के लिए अंतर्राष्ट्रीयकरण नहीं करते हैं?
ग्रेग जैक्सन

@Greg जैक्सन, निश्चित रूप से सीढ़ी। जैसा कि बारूद ने बताया है, PhoneNumberशायद इसकी अपनी कक्षा में है (जो मैंने अब लागू किया है)। लेकिन FullNameक्या वास्तव में वह था जिसने मुझे प्रश्न लिखने के लिए प्रेरित किया। लेकिन मुझे यह पता लगाने में दिलचस्पी है कि क्या सामान्य तौर पर, यह उन चीजों के लिए मॉडल में डेटा स्वरूपण / कंघी, आदि लगाने के लिए समझ में आता है जो ऐप-वाइड लागू करेंगे। नीचे दिए गए जवाबों से, ऐसा लगता है कि यह एक विरोधी पैटर्न नहीं है, लेकिन निर्णय सावधानी से किया जाना चाहिए।
देवकर

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

जवाबों:


9

आपके उदाहरण में, मुझे FullNameगेट्टर (आपके द्वारा दिए गए सभी कारणों के लिए) पसंद है, लेकिन मुझे फॉर्मेटफोनफोन कैप्सूल्टर पसंद नहीं है। कारण यह है: यह शायद इतना आसान नहीं है (एक बार जब आपके पास अंतर्राष्ट्रीय फोन नंबर आदि हैं) और यदि आप एक तरीके से फोन नंबर बनाने के लिए तर्क देते Memberहैं, तो संभावना है कि आपको एक बार रिफ्लेक्टर (या कॉपी-पेस्ट कॉग ) करने की आवश्यकता होगी के लिए एक से स्वरूपित फोन नंबर की जरूरत है Institution, Vendorआदि भी।

EDIT: IMO बेहतर होगा कि PhoneNumberएक Formattedगेट के साथ एक क्लास हो ।


+1 और धन्यवाद। लेकिन क्या होगा अगर मैं वास्तव में एक एक्सटेंशन पद्धति में अपना फोन नंबर फ़ॉर्मेटिंग कोड डालूं? तब कोई भी मॉडल इसका इस्तेमाल कर सकता था, और इसमें कोई रिफैक्टिंग या कॉपी / पेस्टिंग नहीं होगी। यह समाधान अभी भी प्रत्येक फ़ोन नंबर के लिए फ़ॉर्मेटर को लागू करने की तुलना में कम दोहराव वाला होगा जो हर दृश्य में दिखाई देता है।
देवकर

3
उसके लिए एक विस्तार विधि का उपयोग करना "कार्यात्मक अपघटन" एंटीपैटर्न का एक त्वरित तरीका होगा। एक विस्तार विधि का उपयोग करके ( Stringवर्ग के लिए, मुझे लगता है), आप Stringकक्षा को फोन नंबर को प्रारूपित करने का तरीका सिखाते हैं । क्या वास्तव Stringमें फोन नंबर के बारे में जानना कक्षा की जिम्मेदारी है ? मुझे ऐसा नहीं लगता। उस तरह से इस्तेमाल किया, विस्तार विधियों कुछ ऐसा करने के लिए वाक्यविन्यास चीनी हैं जो स्पष्ट रूप से ऑब्जेक्ट उन्मुख नहीं है जैसा कि यह था।
user281377

1
ठीक है, भूल जाओ मैंने कहा विस्तार विधि। प्रेटेंड I ने कहा कि उपयोगिता विधि या फ़ॉर्मेटर क्लास। मैं बस यह कह रहा हूं कि किसी मॉडल को प्राप्त करने वाले या कहीं और प्रारूपण करने के बावजूद, रिफ्लेक्टरिंग / कॉपी पेस्टिंग आवश्यक नहीं होनी चाहिए।
devuxer

1
और मैं एक PhoneNumberवर्ग के विचार को पसंद करता हूं । मैं वैसे भी करने की योजना बना रहा हूं क्योंकि मेरे पास भी PhoneTypeसंपत्ति है।
देवकर

मुझे PhoneNumberउदाहरण वर्ग के रूप में होने का विचार पसंद नहीं है क्योंकि डेटा मूल रूप से है string। बल्कि, यह एक स्थिर वर्ग होना चाहिए जैसे कि विधियाँ public static string Format(string phoneNumber, PhoneNumberStyle style)
श्री एंडरसन

5

कोड लिखते समय आपको जिन चीजों पर विचार करने की आवश्यकता है: क्या यह सही है? क्या यह पठनीय है? क्या यह कुशल है? क्या यह बनाए रखने योग्य है? मैं तर्क देता हूं, जैसा कि @btilly ने उल्लेख किया है, कि यह संस्कृति-विशिष्ट प्रारूपण के कारण बनाए रखने योग्य नहीं है, लेकिन यह प्रश्न अधिक सामान्य प्रतीत होता है कि।

इन जैसे एक्सेसर्स का उपयोग करना आपके कोड को अधिक पठनीय बनाता है, और, आप इसका उपयोग कैसे करते हैं, इस पर निर्भर करते हुए, आपके कोड के अन्य हिस्सों को बहुत अधिक क्लीनर बना सकता है। मेरी राय में, यह बिल्कुल भी गंध नहीं करता है। यह गंध शुरू होगा यदि आप स्ट्रिंग के किसी भी प्रकार के लिए accessors का प्रारूपण था आप (मुद्रित करने के लिए चाहते हो सकता है public string FirstLastName; public string FullName; public string FullNameWithMiddleInitial; public string PhoneNumberWithAreaCode; public string PhoneNumberWithoutAreaCode; public string PhoneNumberWithCountryCode;, आदि)

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


धन्यवाद, ग्रेग। +1। मैं आपके साथ हर संयोजन को रखने के बारे में सहमत हूं। मैं वास्तव में सिर्फ यह साफ करने का प्रयास कर रहा हूं कि कैसे डेटा को देखा जाए।
devuxer

3

एकल जिम्मेदारी सिद्धांत को तोड़ता है। फ़ोन नंबर क्लास क्यों नहीं बनाया, आदि ...?


ठीक है, मैं वास्तव में इससे सहमत हूं (बारूद के जवाब के तहत चर्चा देखें), लेकिन क्या मुझे एक FullNameवर्ग भी बनाना चाहिए ?
देवकर

हां, आपको करना चाहिए, लेकिन आपको "FullName" से "FoolName" तक वर्तनी को सही करना चाहिए। या हो सकता है "PersonalName", क्योंकि यह एक व्यक्ति का नाम है, न कि पूर्ण।
केविन क्लाइन

1
वास्तव में? जब तक दिए गए वर्ग को बढ़ने की उम्मीद नहीं है, बस इसके साथ क्या गलत है? अगर यह बढ़ता है, तो भी फिर से फैक्टर कितना मुश्किल होगा?
जॉब

@ डैनएम: इसके बाद आप जो पूछते हैं, यानी उन्हें अपने पूर्ण कानूनी नाम में टाइप करने के लिए कहें। यदि आप पहले नाम से छांट रहे हैं, तो आप वास्तव में पहले नाम के पहले अक्षर (फिर दूसरे, और इतने पर) को छांट रहे हैं (फिर अगला, फिर इसी तरह), इसलिए नाम समान रूप से समान होंगे।
मैट एलेन


1

आपके उदाहरण के लिए, मैं इसे विशिष्ट स्वरूपों का उपयोग करने के लिए बहुत बड़ी बात के रूप में नहीं देखता। यह एक या दो है और अनुप्रयोग के सभी भाग एक ही प्रारूप का उपयोग करते हैं।

जहां यह निर्णय टूटना शुरू हो जाएगा, जब आपके पास एक ही डेटा कई अलग-अलग स्थानों पर जा रहा होगा, जिसमें विभिन्न स्वरूपों की आवश्यकता होगी

अगर ऐसा हुआ, तो मुझे Memberकक्षा को वापस खींचने के लिए लुभाया जाएगा :

public class Member
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }  
}

और फिर प्रत्येक लक्ष्य के लिए अलग-अलग एडेप्टर करें। उदाहरण के लिए, मान लीजिए कि जानकारी सीएसवी प्रारूप में आवश्यक थी:

public static class CSVMemberAdapter
{
    public static string ToCSV(this Member mbr)
    {
         return mbr.Id + "," + mbr.LastName + "," + mbr.FirstName, "," mbr.PhoneNumber;
    }
}

हमेशा यह मानते हुए कि आपने डेटा को सुरक्षित कर लिया है ताकि कोई अल्पविराम आदि तार में न हो।

एडॉप्टर के लिए एक एक्सटेंशन विधि नहीं है, लेकिन इस मेकअप-केस के लिए यह फिट लगता है।


जब से मैंने C # लिखा है तब से थोड़ी देर हो गई है, लेकिन निश्चित रूप से क्रमबद्धता कक्षाएं हैं जो इसे संभाल सकती हैं, बजाय इसके कि tCSV जैसे ओवर और ओवर और ओवर और ओवर और ओवर और ओवर और ओवर और ओवर से अधिक लिखने के तरीके। और अधिक से अधिक और अधिक से अधिक ...
केविन क्लाइन

@kevin cline: यह इस बात पर निर्भर करता है कि आपको प्रत्येक सिंक में क्या चाहिए। अगर वे सभी की जरूरत है XML, धारावाहिक ठीक है। कई प्रणालियों नहीं है। यदि ऐसा overकई बार किया जाना है, तो डिजाइन में कुछ गड़बड़ है।
पीटर के।

आमतौर पर धारावाहिक बनाने के लिए कई वर्ग होंगे। एक एकल CSV या अन्य धारावाहिक लिखना संभव होना चाहिए जो कि आपके उदाहरण की तरह हाथ से कोड करने के बजाय प्रतिबिंब के माध्यम से अधिकांश कक्षाओं को संभाल सके।
केविन क्लाइन

@kevin cline: हिंसक रूप से सहमत! मैं अभी पूछे गए प्रश्न के लिए कुछ बहुत ही विशिष्ट लिख रहा था। ठोस, सरल उदाहरण चीजों को बेहतर तरीके से समझाते हैं।
पीटर के।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.