उपयोगकर्ता चेतावनी प्रदर्शित करते हुए, गेटर्स और सेटर से बचें


10

पृष्ठभूमि

मैं "क्लीन कोड बुक" पढ़ रहा हूं, और, पार्लेल में, मैं बैंकर अकाउंट की तरह कैलिसथेनिक ऑब्जेक्ट्स काटा पर काम कर रहा हूं, और मैं उस नियम पर अटक गया हूं:

कैलिस्थेनिक वस्तुओं का 9 वां नियम यह है कि हम गेटटर या सेटर का उपयोग नहीं करते हैं।

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

यह मेरे दिमाग में सही अर्थ रखता है, और मैं इस सिद्धांत से पूरी तरह सहमत हूं। समस्या व्यवहार में आती है।

प्रसंग

उदाहरण के लिए, मेरे पास एक एप्लिकेशन है जिसमें मुझे कुछ उपयोगकर्ताओं को सूचीबद्ध करना है, और उपयोगकर्ता विवरण प्रदर्शित करना है।

मेरा उपयोगकर्ता निम्न से बना है:

-> Name
   --> Firstname --> String
   --> Lastname --> String
-> PostalAddress
   --> Street --> String
   --> PostalCode --> String

मुसीबत

जब मैं केवल साधारण जानकारी प्रदर्शित करने की आवश्यकता होती है, तो मुझे गेट्स से बचने के लिए मैं क्या कर सकता हूं या क्या कर सकता हूं ( और मुझे इस बात की पुष्टि करनी होगी कि मुझे एक साधारण में Firstname मान प्रदर्शित करने के लिए उस विशेष क्षेत्र पर अतिरिक्त संचालन की आवश्यकता नहीं है ) यादृच्छिक) आउटपुट समर्थन?

मेरे मन में क्या आता है

एक समाधान बनाना है:

user.getName().getFirstName().getStringValue()

जो परोक्ष रूप से भयानक है, जो कैलिसथेनिक वस्तुओं के कई नियमों को तोड़ रहा है, और डेमेटर कानून को तोड़ रहा है।

एक और कुछ इस तरह होगा:

String firstName = user.provideFirstnameForOutput();
// That would have called in the user object =>
String firstName = name.provideFirstnameForOutput();
// That would have called in the name object =>
String firstName = firstname.provideFirstnameForOutput();

लेकिन मैं इस समाधान के साथ सहज महसूस नहीं करता, कि केवल एक "उच्च क्रम एक्सेसर" लगता है, जैसे मानक गेटटर / सेटर को दरकिनार करना, जो केवल डेमेटर कानून से मेल खाता है ...

कोई उपाय ?

जवाबों:


17

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

आपको अपने एप्लिकेशन के व्यावसायिक-लॉजिक भाग में गेटर्स और सेटर का उपयोग करने से बचना चाहिए, जहां ऑब्जेक्ट्स को संदर्भ प्रदान करने वाले समुच्चय का उपयोग करके संरक्षित किया जाना चाहिए, और विधियों को कमांड के रूप में कार्य करना चाहिए।

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

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

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

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


ठीक है, मुझे लगता है कि मेरी प्रस्तुति की परत के लिए एक कस्टम डीटीओ के लिए मेरी डोमेन इकाई के बीच एक मैपर की तरह ही उस सुझाव के बारे में, जो कुछ एक्सेसर्स के लिए सही होगा?
mfrachet

@ मेराजिन बहुत, हाँ।
एंडी

यह सब कैस्केडिंग सामान वास्तव में अच्छा और चिकना लगता है, उत्तर के लिए धन्यवाद;)
mfrachet

2

कच्चे डेटा तक पहुँच प्रदान करने के बजाय, सोचने की एक दिशा सामान्य स्ट्रिंग प्रारूपण सदस्य फ़ंक्शन प्रदान करना होगा। कुछ इस तरह:

String lastName = user.formatDescription("$(Lastname)");
String fullName = user.formatDescription("$(Lastname), $(Firstname)");
String abbreviated = user.formatDescription("$(FnAbb). $(LnAbb).");

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

String accountName = user.formatDescription("$(firstname).$(lastname)");

आप कुछ सामान्य रूप से उपयोग किए जाने वाले, संभवतः जटिल प्रारूपों को भी एक बार परिभाषित कर सकते हैं, इसलिए आप उदाहरण के लिए कह सकते हैं

String fullAddress = user.formatDescription(User.kAddressFormat);

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

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


5
हालांकि, यह मेरे लिए SRP उल्लंघन जैसा दिखता है। क्या यह किसी Userवस्तु की जिम्मेदारी है कि वह किसी भाषा की व्याख्या और संकलन / व्याख्या करे?
जोर्ग डब्ल्यू मित्तग

@ JörgWMittag जरूरी नहीं है। जैसा कि मैंने कहा, KISS-सिद्धांत वरीयता दी जाएगी। और मैंने कहीं नहीं कहा कि Userवर्ग को इस कार्यक्षमता को स्वयं लागू करना होगा। अगर मेरे पास केवल दो कक्षाएं थीं जो इस तरह की कार्यक्षमता की आवश्यकता थीं, तो आप मुझ पर अपने स्वयं के वर्ग में टेम्पलेट प्रतिस्थापन तंत्र फैक्टरिंग पर शर्त लगा सकते हैं। यह एक उदाहरण है कि आप कैसे अमूर्तता को उठा सकते हैं जो Userएक स्तर प्रदान करता है जहां यह वास्तव में सिर्फ एक डेटा कंटेनर से अधिक है। और मुझे विश्वास है, कि एक्सेसर्स से बचने के बारे में सब कुछ है: structएस के झुंड को संभालने के बजाय ओओपी करना ।
cmaster - मोनिका

तुम्हें पता है कि KISS पूरी तरह से व्यक्तिपरक और SRP उद्देश्य है? KISS आप क्या करना है के बारे में कुछ नहीं बताता है। और जो "सिंपल" है, वह मेरे लिए "सिंपल" नहीं हो सकता। मैं अगर KISS या SRP के साथ बहस की गुणवत्ता में वास्तविक अंतर देखते हैं।
oopexpert
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.