एक अमूर्त वर्ग में क्या कोड शामिल होना चाहिए?


10

मैं अमूर्त वर्गों के उपयोग के बारे में हाल ही में परेशान हूं।

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

कुछ अन्य बार, ऐसा होता है कि कुछ "व्युत्पन्न" वर्गों के निर्माण के बाद अमूर्त वर्ग का निर्माण होता है (चूंकि माता-पिता / अमूर्त वर्ग ऐसा नहीं है, वे अभी तक व्युत्पन्न नहीं हुए हैं, लेकिन आप जानते हैं कि मेरा क्या मतलब है)। इन मामलों में, अमूर्त वर्ग आमतौर पर एक ऐसी जगह के रूप में उपयोग किया जाता है जहां आप किसी भी प्रकार के सामान्य कोड डाल सकते हैं जिसमें वर्तमान व्युत्पन्न वर्ग होते हैं।

उपरोक्त टिप्पणियों के बाद, मैं सोच रहा हूं कि इन दोनों मामलों में से कौन सा नियम होना चाहिए। क्या किसी भी तरह के विवरण को केवल सार वर्ग तक ही सीमित किया जाना चाहिए, क्योंकि वे वर्तमान में सभी व्युत्पन्न वर्गों में सामान्य हैं? क्या सामान्य कोड जो एक उच्च-स्तरीय कार्यक्षमता का हिस्सा नहीं है, होना चाहिए?

क्या ऐसा कोड होना चाहिए जो अमूर्त वर्ग के लिए कोई अर्थ न रखता हो, क्योंकि यह केवल इसलिए होता है क्योंकि यह व्युत्पन्न वर्गों के लिए सामान्य है?

मुझे एक उदाहरण दें: सार वर्ग A में एक विधि () और एक सार विधि aq () है। विधि aq (), दोनों व्युत्पन्न वर्गों AB और AC में, विधि b () का उपयोग करती है। क्या बी () को A में स्थानांतरित किया जाना चाहिए? यदि हाँ, तो यदि कोई व्यक्ति केवल A को देखता है (आइए दिखाते हैं कि AB और AC नहीं हैं), b () का अस्तित्व बहुत मायने नहीं रखेगा! क्या यह खराब चीज़ है? क्या किसी को एक अमूर्त वर्ग में देखने और समझने में सक्षम होना चाहिए कि व्युत्पन्न वर्गों का दौरा किए बिना क्या चल रहा है?

सच कहूं, तो यह पूछने के समय, मैं यह मानता हूं कि एक अमूर्त वर्ग लिखना जो बिना किसी व्युत्पन्न वर्ग को देखने के लिए समझ में आता है, यह साफ कोड और स्वच्छ वास्तुकला का विषय है। That वास्तव में एक सार वर्ग के विचार को पसंद नहीं करते हैं जो किसी भी तरह के कोड के लिए डंप की तरह काम करता है सभी व्युत्पन्न वर्गों में सामान्य होता है।

आप क्या सोचते / अभ्यास करते हैं?


7
एक "नियम" क्यों होना चाहिए?
रॉबर्ट हार्वे

1
Writing an abstract class that makes sense without having to look in the derived classes is a matter of clean code and clean architecture.-- क्यों? क्या यह संभव नहीं है कि, एक आवेदन को डिजाइन करने और विकसित करने के दौरान, मुझे पता चलता है कि कई वर्गों में सामान्य कार्यक्षमता है जो स्वाभाविक रूप से एक अमूर्त वर्ग में बदल सकती है? क्या मुझे व्युत्पन्न वर्गों के लिए कोई भी कोड लिखने से पहले हमेशा यह अनुमान लगाने के लिए पर्याप्त होना चाहिए? अगर मैं इस कसौटी पर खरा नहीं उतरता हूं, तो क्या मुझे इस तरह के रिफलेक्टर करने से मना किया गया है? क्या मुझे अपना कोड टॉस करना चाहिए और शुरू करना चाहिए?
रॉबर्ट हार्वे

क्षमा करें, अगर मुझे गलत समझा गया था! मैं यह कहने की कोशिश कर रहा था कि जो मैं महसूस कर रहा हूं (फिलहाल) एक बेहतर अभ्यास के रूप में और इसका मतलब यह नहीं है कि एक पूर्ण नियम होना चाहिए। इसके अलावा, मैं यह नहीं कह रहा हूं कि अमूर्त वर्ग से संबंधित कोई भी कोड केवल अग्रिम में लिखा जाना चाहिए। मैं वर्णन कर रहा था कि कैसे, व्यवहार में, एक अमूर्त वर्ग उच्च-स्तरीय कोड (जो व्युत्पन्न लोगों के लिए एक टेम्पलेट के रूप में कार्य करता है) के साथ-साथ निम्न-स्तरीय कोड के साथ समाप्त होता है (आप समझ नहीं सकते कि यह आपके लिए प्रयोज्य नहीं है। व्युत्पन्न वर्ग)।
अलेक्जेंड्रोस गुगौसिस

एक सार्वजनिक आधार वर्ग के लिए @RobertHarvey, आपको व्युत्पन्न वर्गों को देखने से प्रतिबंधित किया जाएगा। आंतरिक कक्षाओं के लिए, इससे कोई फर्क नहीं पड़ता।
फ्रैंक हिलमैन

जवाबों:


4

मुझे एक उदाहरण दें: सार वर्ग A में एक विधि () और एक सार विधि aq () है। विधि aq (), दोनों व्युत्पन्न वर्गों AB और AC में, विधि b () का उपयोग करती है। क्या बी () को A में स्थानांतरित किया जाना चाहिए? यदि हाँ, तो यदि कोई व्यक्ति केवल A को देखता है (आइए दिखाते हैं कि AB और AC नहीं हैं), b () का अस्तित्व बहुत मायने नहीं रखेगा! क्या यह खराब चीज़ है? क्या किसी को एक अमूर्त वर्ग में देखने और समझने में सक्षम होना चाहिए कि व्युत्पन्न वर्गों का दौरा किए बिना क्या चल रहा है?

आपका पूछना क्या है, कहां रखना है b(), और किसी अन्य अर्थ में एक सवाल यह है कि क्या Aतत्काल सुपर क्लास के लिए सबसे अच्छा विकल्प है ABऔर AC

ऐसा लगता है कि तीन विकल्प हैं:

  1. b()दोनों ABऔर में छोड़ देंAC
  2. एक मध्यवर्ती वर्ग बनाने ABAC-Parentकि से विरासत में मिली Aऔर कहा कि प्रस्तुत किया b()है, और फिर के लिए तत्काल सुपर वर्ग के रूप में प्रयोग किया जाता है ABऔरAC
  3. डाल दिया (यह जानने b()में Aनहीं कि भविष्य का दूसरा वर्ग ADचाहेगा b()या नहीं)

  1. नहीं किया जा रहा से ग्रस्त सूखी
  2. YAGNI से ग्रस्त है ।
  3. तो, कि यह एक छोड़ देता है।

एक अन्य वर्ग ADजो b()खुद को प्रस्तुत नहीं करना चाहता है, (3) सही विकल्प की तरह लगता है।

एक ADप्रस्तुत के रूप में ऐसे समय में , हम (2) में दृष्टिकोण के लिए रिफ्लेक्टर कर सकते हैं - आखिर यह सॉफ्टवेयर है!


7
एक 4 वाँ विकल्प है। b()किसी भी वर्ग में मत डालो । इसे एक निशुल्क फ़ंक्शन बनाएं जो अपने सभी डेटा को तर्क के रूप में लेता है और दोनों के पास है ABऔर ACइसे कॉल करता है। इसका मतलब है कि जब आप जोड़ते हैं तो आपको इसे स्थानांतरित करने या किसी और वर्ग को बनाने की आवश्यकता नहीं होती है AD
user1118321

1
@ user1118321, बॉक्स के बाहर उत्कृष्ट, अच्छी सोच। अगर b()कोई उदाहरण लंबे समय तक जीवित रहने की जरूरत है, तो विशेष रूप से समझ में आता है ।
एरिक इद्दत

(3) में मुझे क्या परेशानी है कि अमूर्त वर्ग अब व्यवहार के एक आत्म निहित टुकड़े का वर्णन नहीं करता है। यह बिट्स और कोड के टुकड़े हैं और मैं इस और सभी व्युत्पन्न वर्गों के बीच पीछे-पीछे जाने के बिना सार वर्ग कोड को नहीं समझ सकता।
अलेक्जेंड्रोस गुगौसिस

क्या आप आधार / डिफ़ॉल्ट बना सकते हैं जो अमूर्त होने के बजाय acकॉल करता है ? bac
एरिक Eidt

3
मेरे लिए, सबसे महत्वपूर्ण सवाल यह है कि AB और AC दोनों एक ही विधि b () का उपयोग क्यों करते हैं। अगर यह सिर्फ संयोग है, तो मैं एबी और एसी में दो समान कार्यान्वयन छोड़ दूंगा। लेकिन शायद यह इसलिए है क्योंकि एबी और एसी के लिए कुछ सामान्य अमूर्तता मौजूद है। मेरे लिए, DRY अपने आप में इतना मूल्य नहीं है, लेकिन एक संकेत है कि आपने शायद कुछ उपयोगी अमूर्त को याद किया।
राल्फ क्लेरहॉफ

2

एक सार वर्ग का मतलब विभिन्न कार्यों या डेटा के लिए डंपिंग ग्राउंड नहीं है, जो कि सार वर्ग में फेंक दिया जाता है क्योंकि यह सुविधाजनक है।

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

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

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

हालाँकि हमेशा बदलाव के सवाल हैं, क्या बदलने जा रहा है और यह कैसे बदलेगा और क्यों बदलेगा।

वंशानुक्रम स्रोत के भंगुर और नाजुक निकायों को जन्म दे सकता है (देखें इनहेरिटेंस: बस पहले से ही इसका उपयोग करना बंद कर दें! )।

नाजुक आधार वर्ग की समस्या ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग सिस्टम की एक मूलभूत स्थापत्य समस्या है, जहाँ बेस क्लास (सुपरक्लास) को "नाजुक" माना जाता है, क्योंकि बेस क्लास द्वारा सुरक्षित रूप से सुरक्षित संशोधन, जब व्युत्पन्न वर्गों द्वारा विरासत में मिला होता है, तो व्युत्पन्न वर्ग में खराबी हो सकती है। । प्रोग्रामर यह निर्धारित नहीं कर सकता है कि क्या आधार वर्ग के तरीकों को अलग-थलग करके जांच करने से एक बेस क्लास परिवर्तन सुरक्षित है या नहीं।


मुझे यकीन है कि कोई भी OOP अवधारणा समस्याओं का कारण बन सकती है अगर इसका दुरुपयोग या अधिक उपयोग या दुरुपयोग किया जाता है! इसके अलावा, यह धारणा बनाते हुए कि बी () एक पुस्तकालय पद्धति है (उदाहरण के लिए अन्य निर्भरता के बिना एक शुद्ध कार्य) मेरे प्रश्न के दायरे को कम करती है। इससे बचते हैं।
अलेक्जेंड्रोस गुगौसिस

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

क्षमा करें, अगर मैं स्पष्ट नहीं था! मैंने कई उदाहरणों में से एक के रूप में शुद्ध कार्य का उल्लेख किया (आपने अधिक दिया है)।
अलेक्जेंड्रोस गुगौसिस

1

आपका प्रश्न अमूर्त वर्गों के लिए या तो दृष्टिकोण या दृष्टिकोण बताता है। लेकिन मुझे लगता है कि आपको उन्हें अपने टूलबॉक्स में सिर्फ एक और उपकरण के रूप में समझना चाहिए। और फिर सवाल यह बन जाता है: किन नौकरियों / समस्याओं के लिए सार कक्षाएं सही उपकरण हैं?

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

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

मुझे लगता है कि आपका पहला उदाहरण मूल रूप से टेम्पलेट विधि पैटर्न का वर्णन है (मुझे गलत होने पर सही करें), इसलिए मैं इसे अमूर्त कक्षाओं के पूरी तरह से मान्य उपयोग के मामले के रूप में मानूंगा।

कुछ अन्य बार, ऐसा होता है कि कुछ "व्युत्पन्न" वर्गों के निर्माण के बाद अमूर्त वर्ग का निर्माण होता है (चूंकि माता-पिता / अमूर्त वर्ग ऐसा नहीं है, वे अभी तक व्युत्पन्न नहीं हुए हैं, लेकिन आप जानते हैं कि मेरा क्या मतलब है)। इन मामलों में, अमूर्त वर्ग आमतौर पर एक ऐसी जगह के रूप में उपयोग किया जाता है जहां आप किसी भी प्रकार के सामान्य कोड डाल सकते हैं जिसमें वर्तमान व्युत्पन्न वर्ग होते हैं।

आपके दूसरे उदाहरण के लिए, मुझे लगता है कि अमूर्त वर्गों का उपयोग करना इष्टतम विकल्प नहीं है, क्योंकि साझा तर्क और डुप्लिकेट कोड से निपटने के लिए बेहतर तरीके हैं। चलो कहते हैं कि तुम सार वर्ग है A, व्युत्पन्न वर्ग Bऔर Cऔर दोनों व्युत्पन्न वर्ग विधि के रूप में कुछ तर्क का हिस्सा s()। दोहराव से छुटकारा पाने के लिए सही दृष्टिकोण पर निर्णय लेने के लिए, यह जानना महत्वपूर्ण है कि विधि s()सार्वजनिक इंटरफ़ेस का हिस्सा है या नहीं।

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

यदि s()सार्वजनिक इंटरफ़ेस का हिस्सा है, तो यह थोड़ा और मुश्किल हो जाता है। उस धारणा के तहत जिसका s()कोई संबंध नहीं है Bऔर इससे Cसंबंधित होने के कारण A, आपको s()अंदर नहीं रखना चाहिए A। तो फिर इसे कहां रखा जाए? मैं एक अलग इंटरफ़ेस घोषित करने के लिए तर्क दूंगा I, जो परिभाषित करता है s()। फिर, यदि आप एक अलग वर्ग है कि लागू करने के लिए तर्क होता है बनाने चाहिए s()और दोनों Bऔर Cउस पर निर्भर करते हैं।

अंत में, यहाँ SO पर एक दिलचस्प सवाल के उत्कृष्ट उत्तर की एक कड़ी है जो आपको यह तय करने में मदद कर सकती है कि इंटरफ़ेस के लिए कब जाना है और किसी अमूर्त वर्ग के लिए कब:

एक अच्छा अमूर्त वर्ग कोड की मात्रा को कम कर देगा जिसे फिर से लिखना होगा क्योंकि यह कार्यक्षमता या राज्य साझा किया जा सकता है।


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

1

मुझे लगता है कि आप वस्तु उन्मुखीकरण की बात को याद कर रहे हैं, दोनों तार्किक और तकनीकी रूप से। आप दो परिदृश्यों का वर्णन करते हैं: एक आधार वर्ग और बहुरूपता में प्रकार के सामान्य व्यवहार को समूहीकृत करना। ये दोनों एक अमूर्त वर्ग के वैध अनुप्रयोग हैं। लेकिन आपको कक्षा को अमूर्त बनाना चाहिए या नहीं यह आपके विश्लेषणात्मक मॉडल पर निर्भर करता है, न कि तकनीकी संभावनाओं पर।

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

फिर आप स्तरों की बात करते हैं। जब विरासत की बात आती है तो स्तर सौदे का हिस्सा नहीं होते हैं। न ही आम डेटा या सामान्य व्यवहार को पहचान रहा है, यह एक तकनीकी दृष्टिकोण है जो संभवतः मदद नहीं करेगा। आपको एक स्टीरियोटाइप को पहचानना चाहिए और फिर बेस क्लास डालना चाहिए। यदि ऐसा कोई स्टीरियोटाइप नहीं है, तो आप कई वर्गों द्वारा लागू किए गए कुछ इंटरफेस के साथ बेहतर हो सकते हैं।

अपने सदस्यों के साथ मिलकर अपने अमूर्त वर्ग का नाम समझ में आना चाहिए। यह तकनीकी और तार्किक रूप से, किसी भी व्युत्पन्न वर्ग से स्वतंत्र होना चाहिए। जैसे पशु में एक सार विधि हो सकती है खाओ (जो बहुरूप होगा) और बूलियन अमूर्त गुण IsPet और IsLif पशुधन है, जो बिल्लियों या कुत्तों या सूअरों के बारे में जाने बिना समझ में आता है। किसी भी निर्भरता (तकनीकी या तार्किक) को एक ही रास्ता जाना चाहिए: वंश से आधार तक। बेस क्लासेस को खुद भी अवरोही कक्षाओं का ज्ञान नहीं होना चाहिए।


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

"बेस क्लासेस को खुद भी अवरोही कक्षाओं का ज्ञान नहीं होना चाहिए।" मैं इससे पूरी तरह सहमत हूं। एक अभिभावक वर्ग (अमूर्त या नहीं) में व्यावसायिक तर्क का एक आत्म निहित अंश होना चाहिए, जिसे समझने के लिए बाल वर्ग कार्यान्वयन का निरीक्षण करने की आवश्यकता नहीं है।
अलेक्जेंड्रोस गुगौसिस

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

0

पहला मामला , आपके प्रश्न से:

ऐसे मामलों में, एक अमूर्त वर्ग एक खाका की तरह काम करता है, कार्यक्षमता का एक उच्च स्तरीय विवरण या जिसे आप इसे कॉल करना चाहते हैं।

दूसरा मामला:

कुछ अन्य समय ... अमूर्त वर्ग आमतौर पर एक ऐसी जगह के रूप में उपयोग किया जाता है जहां आप किसी भी प्रकार का सामान्य कोड डाल सकते हैं जिसमें वर्तमान व्युत्पन्न वर्ग होते हैं।

फिर, आपका प्रश्न :

मैं सोच रहा हूं कि इन दो मामलों में से कौन सा नियम होना चाहिए। ... क्या कोड होना चाहिए जो कि अमूर्त वर्ग के लिए कोई अर्थ नहीं हो सकता है क्योंकि यह केवल इसलिए होता है क्योंकि यह व्युत्पन्न वर्गों के लिए सामान्य है?

IMO आपके पास दो अलग-अलग परिदृश्य हैं, इसलिए आप यह तय करने के लिए एक भी नियम नहीं बना सकते हैं कि किस डिज़ाइन को लागू किया जाना चाहिए।

पहले मामले के लिए, हमारे पास अन्य उत्तरों में पहले से उल्लिखित टेम्प्लेट मेथड पैटर्न जैसी चीजें हैं ।

दूसरे मामले के लिए, आपने एब्सट्रैक्ट क्लास ए प्राप्तिंग एब () विधि का उदाहरण दिया; IMO b () पद्धति को केवल तभी स्थानांतरित किया जाना चाहिए जब यह सभी अन्य व्युत्पन्न वर्गों के लिए समझ में आता है। दूसरे शब्दों में, यदि आप इसे स्थानांतरित कर रहे हैं क्योंकि यह दो स्थानों पर उपयोग किया जाता है, तो शायद यह एक अच्छा विकल्प नहीं है, क्योंकि कल एक नया ठोस व्युत्पन्न वर्ग हो सकता है, जिस पर b () का कोई मतलब नहीं है। साथ ही, जैसा कि आपने कहा, यदि आप A को अलग से देखते हैं और b () का उस संदर्भ में भी कोई मतलब नहीं है, तो शायद यह एक संकेत है कि यह एक अच्छा डिज़ाइन विकल्प नहीं है।


-1

मैंने कुछ समय पहले बिल्कुल वही सवाल किए हैं!

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

abstract class AbstractProtocol
{
    /**
     * @return array Registration params to send
     */
    abstract protected function assembleRegistrationPart();

    /**
     * @return array Payment params to send
     */
    abstract protected function assemblePaymentPart();

    protected function doSend(array $data)
    {
        return
            (new HttpClient(
                [
                    'timeout' => 60,
                    'encoding' => 'utf-8',
                    'language' => 'en',
                ]
            ))
                ->send($data);
    }

    protected function log(array $data)
    {
        $header = 'Here is a request to external system!';
        $body = implode(', ', $this->maskData($data));
        Logger::log($header . '. \n ' . $body);
    }
}

class ClassicProtocol extends AbstractProtocol
{
    public function send()
    {
        $registration = $this->assembleRegistrationPart();
        $payment = $this->assemblePaymentPart();
        $specificParams = $this->assembleClassicSpecificPart();

        $dataToSend =
            array_merge(
                $registration, $payment, $specificParams
            );

        $this->log($dataToSend);

        $this->doSend($dataToSend);
    }

    protected function assembleRegistrationPart()
    {
        return ['hello' => 'there'];
    }

    protected function assemblePaymentPart()
    {
        return ['pay' => 'yes'];
    }
}

इस तरह के कोड से संकेत मिलता है कि मैं विरासत का दुरुपयोग करता हूं। इस तरह इसे फिर से बनाया जा सकता है:

class ClassicProtocol
{
    private $request;
    private $logger;

    public function __construct(Request $request, Logger $logger, Client $client)
    {
        $this->request = $request;
        $this->client = $client;
        $this->logger = $logger;
    }

    public function send()
    {
        $this->logger->log($this->request->getData());
        $this->client->send($this->request->getData());
    }
}

$protocol =
    new ClassicProtocol(
        new PaymentRequest(
            new RegistrationData(),
            new PaymentData(),
            new ClassicSpecificData()
        ),
        new ClassicLogger(),
        new ClassicClient()
    );

class RegistrationData
{
    public function getData()
    {
        return ['hello' => 'there'];
    }
}

class PaymentData
{
    public function getData()
    {
        return ['pay' => 'yes'];
    }
}

class ClassicLogger
{
    public function log(array $data)
    {
        $header = 'Here is a request to external system!';
        $body = implode(', ', $this->maskData($data));
        Logger::log($header . '. \n ' . $body);
    }
}
class ClassicClient
{
    private $properties;

    public function __construct()
    {
        $this->properties =
            [
                'timeout' => 60,
                'encoding' => 'utf-8',
                'language' => 'en',
            ];
    }
}

तब से मैं विरासत का इलाज बहुत सावधानी से करता हूं क्योंकि मुझे कई बार चोट लगी थी।

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


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