बड़े इंटरफेस को विभाजित करें


9

मैं एक डेटाबेस तक पहुँचने के लिए लगभग 50 विधियों के साथ एक बड़े इंटरफ़ेस का उपयोग कर रहा हूँ। इंटरफ़ेस मेरा एक सहयोगी द्वारा लिखा गया है। हमने इस पर चर्चा की:

मैं: 50 तरीके बहुत ज्यादा हैं। यह एक कोड गंध है।
सहकर्मी: मैं इसके बारे में क्या करूंगा? आप डीबी पहुंच चाहते हैं - आपके पास है।
Me: हाँ, लेकिन यह अस्पष्ट और भविष्य में शायद ही बनाए रखने योग्य है।
सहकर्मी: ठीक है, आप सही हैं, यह अच्छा नहीं है। तब इंटरफ़ेस कैसा दिखना चाहिए?
मैं: कैसे 5 तरीके हैं जो वस्तुओं को लौटाते हैं, जैसे, 10 तरीके प्रत्येक?

Mmmh, लेकिन यह एक ही नहीं होगा? क्या यह वास्तव में अधिक स्पष्टता की ओर ले जाता है? क्या यह प्रयास के लायक है?

हर अब और फिर मैं ऐसी स्थिति में हूं जहां मुझे एक इंटरफ़ेस चाहिए और पहली चीज जो दिमाग में आती है वह है एक बड़ा इंटरफ़ेस। क्या इसके लिए एक सामान्य डिजाइन पैटर्न है?


अपडेट (सिज़ुआन की टिप्पणी पर प्रतिक्रिया):

"तरह के तरीके": यह डेटाबेस से डेटा लाने के लिए एक इंटरफ़ेस है। सभी विधियों में फॉर्म (छद्मकोश) है

List<Typename> createTablenameList()

तरीके और टेबल 1-1-संबंध में बिल्कुल नहीं हैं, इस तथ्य पर जोर अधिक है कि आपको हमेशा किसी प्रकार की सूची मिलती है जो डेटाबेस से आती है।


12
गुम प्रासंगिक जानकारी है (आपके पास किस तरह के तरीके हैं)। वैसे भी, मेरा अनुमान है: यदि आप केवल संख्या से विभाजित करते हैं तो आपका सहयोगी सही है, आप कुछ भी सुधार नहीं कर रहे हैं। एक संभावित डिवीजन मानदंड "इकाई" (लगभग एक तालिका के समतुल्य) द्वारा लौटाया जाएगा (इसलिए, UserDaoएक CustomerDaoऔर एक ProductDao)
SJuan76

वास्तव में कुछ टेबल "टेबल" बनाने वाले अन्य तालिकाओं के करीब शब्दार्थ हैं। तो विधियां करें।
तोबिसीमनोबी

क्या यह कोड देखना संभव है? मुझे पता है कि यह 4 साल का है और आपने शायद अब तक इसे ठीक कर लिया है: डी बट मैं इस समस्या के बारे में सोचना पसंद करूंगा। मैंने कुछ इस तरह से पहले हल किया।
clankill3r

@ clankill3r वास्तव में मेरे पास उस विशिष्ट इंटरफ़ेस तक कोई पहुंच नहीं है जिसने मुझे ऊपर दिए गए प्रश्न को पोस्ट करने के लिए बनाया। हालांकि समस्या अधिक सामान्य है। लगभग 50 तालिकाओं के साथ DB की कल्पना करें और प्रत्येक तालिका के लिए एक विधि जैसेList<WeatherDataRecord> createWeatherDataTable() {db.open(); return db.select("*", "tbl_weatherData");}
TobiMcNamobi

जवाबों:


16

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

इसे ठीक करने के लिए एक भी पैटर्न नहीं है, लेकिन वांछित स्थिति का वर्णन करने वाला सिद्धांत इंटरफ़ेस अलगाव सिद्धांत (SOLID में 'I') है, जिसमें कहा गया है कि किसी भी ग्राहक को उन तरीकों पर निर्भर रहने के लिए मजबूर नहीं किया जाना चाहिए जो इसका उपयोग नहीं करते हैं ।

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

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


यह और utnapistim का जवाब वास्तव में बहुत अच्छा है।
टोबिम्काम्बोबी

13

सहकर्मी: ठीक है, आप सही हैं, यह अच्छा नहीं है। तब इंटरफ़ेस कैसा दिखना चाहिए?

मैं: कैसे 5 तरीके हैं जो वस्तुओं को लौटाते हैं, जैसे, 10 तरीके प्रत्येक?

यह अच्छा मापदंड नहीं है (वास्तव में उस बयान में कोई मापदंड नहीं है)। आप उनके द्वारा समूह बना सकते हैं (अपने आवेदन को मेरे उदाहरण के लिए एक वित्तीय लेनदेन ऐप है):

  • कार्यक्षमता (आवेषण, अद्यतन, चयन, लेनदेन, मेटाडेटा, स्कीमा, आदि)
  • इकाई (उपयोगकर्ता DAO , जमा DAO, आदि)
  • आवेदन क्षेत्र (वित्तीय लेनदेन, उपयोगकर्ता प्रबंधन, योग आदि)
  • अमूर्त स्तर (सभी टेबल एक्सेस कोड एक अलग मॉड्यूल है; सभी चुनिंदा एपीआई अपने-अपने पदानुक्रम में हैं, लेन-देन समर्थन अलग है, एक मॉड्यूल में सभी रूपांतरण कोड, एक मॉड्यूल में सभी सत्यापन कोड, आदि)

Mmmh, लेकिन यह एक ही नहीं होगा? क्या यह वास्तव में अधिक स्पष्टता की ओर ले जाता है? क्या यह प्रयास के लायक है?

यदि आप सही मानदंड चुनते हैं, तो निश्चित रूप से। यदि आप नहीं करते हैं, तो निश्चित रूप से नहीं :)।

कुछ उदाहरण:

  • पर नज़र ADODB वस्तुओं OO पुरातन का एक साधारण उदाहरण के लिए (अपने DB एपीआई शायद पहले से ही इस प्रदान करता है)

  • उच्च स्तर के अमूर्त स्तर वाले डेटा मॉडल के विचार के लिए Django डेटा मॉडल ( https://docs.djangoproject.com/en/dev/topics/db/models/ ) देखें ( संभवतः C ++ में आपको शायद कुछ अधिक बायलर प्लेट की आवश्यकता होगी कोड, लेकिन यह एक अच्छा विचार है)। यह कार्यान्वयन MVC डिज़ाइन पैटर्न के भीतर एक "मॉडल" भूमिका को ध्यान में रखकर बनाया गया है।

  • एक फ्लैट एपीआई विचार ( http://www.sqlite.org/c3ref/funclist.html ) के लिए sqlite एपीआई देखें , जिसमें केवल कार्यात्मक आदिम (C API) शामिल हैं।


3

हर अब और फिर मैं एक ऐसी स्थिति में हूं जहां मुझे एक इंटरफ़ेस चाहिए और पहली बात जो दिमाग में आती है वह है एक बड़ा इंटरफ़ेस। क्या इसके लिए एक सामान्य डिजाइन पैटर्न है?

यह एक डिजाइन विरोधी पैटर्न है जिसे अखंड वर्ग कहा जाता है । किसी कक्षा या इंटरफ़ेस में 50 विधियाँ होना SRP का संभावित उल्लंघन है । अखंड वर्ग के बारे में आता है क्योंकि यह हर किसी के लिए सब कुछ होने की कोशिश करता है।

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

कैसे के बारे में 5 तरीके जो वस्तुओं को लौटाते हैं, जैसे, 10 तरीके प्रत्येक?

इससे पता चलता है कि जब सभी वस्तुएं तुरंत चालू होती हैं, तो सभी भूमिकाओं को तात्कालिक किया जाता है। लेकिन तात्कालिक भूमिकाएँ आपको क्यों नहीं चाहिए? इसके बजाय, उस भूमिका को तुरंत संदर्भित करें जिसमें आपको वास्तव में इसकी आवश्यकता है।

यदि आप पाते हैं कि DCI की ओर रिफैक्टिंग स्पष्ट नहीं है, तो आप एक साधारण विज़िटर पैटर्न के साथ जा सकते हैं । यह उपयोग के मामले संदर्भों के निर्माण पर जोर दिए बिना एक समान लाभ प्रदान करता है।

संपादित करें: इस पर मेरी सोच कुछ बदल गई है। मैंने एक वैकल्पिक उत्तर प्रदान किया।


1

यह मुझे लगता है कि हर दूसरे जवाब को याद कर रहा है। मुद्दा यह है कि एक इंटरफ़ेस को आदर्श रूप से व्यवहार के परमाणु भाग को परिभाषित करना चाहिए। यही कारण है कि मैं SOLID में I

एक वर्ग के पास एक जिम्मेदारी होनी चाहिए, लेकिन इसमें अभी भी कई व्यवहार शामिल हो सकते हैं। एक विशिष्ट डेटाबेस क्लाइंट ऑब्जेक्ट के साथ छड़ी करने के लिए, यह पूर्ण CRUD कार्यक्षमता प्रदान कर सकता है। यह चार व्यवहार होंगे: बनाना, पढ़ना, अपडेट करना और हटाना। एक शुद्ध SOLID दुनिया में डेटाबेस क्लाइंट IDatabaseClient नहीं बल्कि ICreator, IReader, IUpdater और IDeleter को लागू करेगा।

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

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

तो हां, 50 विधियां एक गंध है लेकिन यह इरादे और उद्देश्य पर निर्भर करता है कि यह खराब है या नहीं। यह निश्चित रूप से आदर्श नहीं है।


0

डेटा एक्सेस लेयर्स में एक वर्ग से जुड़े बहुत सारे तरीके होते हैं। यदि आपने कभी एंटिटी फ्रेमवर्क या अन्य ORM टूल के साथ काम किया है, तो आप देखेंगे कि वे 100s तरीके उत्पन्न करते हैं। मुझे लगता है कि आप और आपके सहयोगी इसे मैन्युअल रूप से लागू कर रहे हैं। यह एक कोड गंध आवश्यक नहीं है, लेकिन यह देखने के लिए बहुत सुंदर नहीं है। आपके डोमेन को जाने बिना, यह कहना मुश्किल है।


तरीके या गुण?
जेएफओ

0

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

इसका मतलब यह है कि वस्तुओं को कार्यक्रमों में पारित किया गया है, आदि को व्यवहार के सेट के साथ सार संस्थाओं के रूप में सोचा जा सकता है। ऑब्जेक्ट को एक भूमिका निभाने के रूप में सोचा जा सकता है जो प्रोटोकॉल का कुछ सेट है। एक व्यक्ति (ठोस प्रकार) एक आदमी, एक पिता, एक पति, एक दोस्त और एक कर्मचारी हो सकता है लेकिन मैं कई कार्यों की कल्पना नहीं कर सकता जो कि इकाई को उन 2 से अधिक का योग मानते हैं।

मुझे लगता है कि यह संभव है कि एक जटिल वस्तु कई अलग-अलग प्रोटोकॉल का पालन कर सकती है, लेकिन आप अभी भी 50-विधि एपीआई के लिए मुश्किल से दबाए जाएंगे। अधिकांश प्रोटोकॉल में 1 या 2 विधियां हैं, शायद 3, लेकिन कभी 50 नहीं! किसी भी इकाई जिसमें 50 विधियां हैं, को अपनी जिम्मेदारियों के साथ प्रत्येक के छोटे घटकों का एक समूह बनाया जाना चाहिए। बड़े पैमाने पर इकाई एक सरल इंटरफ़ेस प्रस्तुत करती है जो एब्स के कुल योग को दूर करती है।

वस्तुओं और विधियों के संदर्भ में सोचने के बजाय, अमूर्त और अनुबंधों के संदर्भ में सोचना शुरू करें और कुछ संदर्भों में विषय क्या भूमिका निभाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.