क्या केवल एकल (सार्वजनिक) पद्धति वाली कक्षाएं एक समस्या है?


51

मैं वर्तमान में एक सॉफ्टवेयर प्रोजेक्ट पर काम कर रहा हूं जो वीडियो निगरानी फुटेज पर संपीड़न और अनुक्रमण करता है। संपीड़न पृष्ठभूमि और अग्रभूमि वस्तुओं को विभाजित करके काम करता है, फिर पृष्ठभूमि को स्थिर छवि के रूप में सहेजता है, और अग्रभूमि को प्रेत के रूप में।

हाल ही में, मैंने उन कुछ वर्गों की समीक्षा की है, जिन्हें मैंने परियोजना के लिए डिज़ाइन किया है।

मैंने देखा कि कई वर्ग ऐसे हैं जिनके पास केवल एक ही सार्वजनिक तरीका है। इन वर्गों में से कुछ हैं:

  • VideoCompressor (एक compressविधि के साथ जो टाइप के इनपुट वीडियो में लेता है RawVideoऔर टाइप का आउटपुट वीडियो देता है CompressedVideo)।
  • VideoSplitter (एक splitविधि के साथ जो टाइप के इनपुट वीडियो में लेता है RawVideoऔर 2 आउटपुट वीडियो का वेक्टर देता है, प्रत्येक प्रकार का RawVideo)।
  • VideoIndexer (एक indexविधि के साथ जो टाइप के इनपुट वीडियो में लेता है RawVideoऔर टाइप का वीडियो इंडेक्स देता है VideoIndex)।

मैं अपने आप को प्रत्येक वर्ग instantiating जैसे कॉल करने के लिए लगता है VideoCompressor.compress(...), VideoSplitter.split(...), VideoIndexer.index(...)

सतह पर, मुझे लगता है कि वर्ग के नाम उनके इच्छित कार्य के लिए पर्याप्त वर्णनात्मक हैं, और वे वास्तव में संज्ञा हैं। इसके अलावा, उनके तरीके भी क्रिया हैं।

क्या यह वास्तव में एक समस्या है?


14
यह भाषा पर निर्भर करता है। C ++ या पाइथन जैसी बहु-प्रतिमान भाषा में, इन वर्गों का कोई व्यवसाय नहीं है: उनके "तरीके" मुक्त कार्य होने चाहिए।

3
@ डायलेन: सी ++ में भी, आप आमतौर पर मॉड्यूल बनाने के लिए कक्षाओं का उपयोग करते हैं, भले ही आपको पूर्ण "ओओ क्षमताओं" की आवश्यकता न हो। वास्तव में, "फ्री फ़ंक्शंस" को एक साथ मॉड्यूल के लिए समूहीकृत करने के बजाय नामस्थान का उपयोग करने का विकल्प है, लेकिन मुझे इसमें कोई लाभ नहीं दिखता है।
डॉक ब्राउन

5
@DocBrown: C ++ में इसके लिए नाम स्थान हैं। वास्तव में आधुनिक सी ++ में आप अक्सर तरीकों के लिए मुफ्त कार्यों का उपयोग करते हैं, क्योंकि वे सभी तर्कों के लिए (स्टैटिकली) अतिभारित हो सकते हैं जबकि विधियां केवल इनवोक के लिए अतिभारित हो सकती हैं।
जन हुदेक

2
@DocBrown: यह सवाल का एक बहुत ही कोर है। फ़ंक्शन के पर्याप्त रूप से जटिल होने पर केवल एक "बाहरी" पद्धति वाले नामस्थानों का उपयोग करने वाले मॉड्यूल पूरी तरह से ठीक हैं। क्योंकि नामस्थान किसी भी चीज़ का प्रतिनिधित्व करने का दिखावा नहीं करते हैं और ऑब्जेक्ट-ओरिएंटेड होने का नाटक नहीं करते हैं। कक्षाएं करते हैं, लेकिन इस तरह की कक्षाएं वास्तव में सिर्फ नामस्थान हैं। बेशक जावा में आपके पास कोई फ़ंक्शन नहीं हो सकता है, इसलिए यह परिणाम है। जावा पर शर्म आती है।
Jan Hudec

2
संबंधित (लगभग एक डुप्लिकेट): प्रोग्रामर.स्टैकएक्सचेंज.
com

जवाबों:


87

नहीं, यह एक समस्या नहीं है, काफी विपरीत है। यह वर्ग के प्रतिरूपकता और स्पष्ट जिम्मेदारी का संकेत है। दुबला इंटरफ़ेस उस वर्ग के उपयोगकर्ता के दृष्टिकोण से समझ लेना आसान है, और यह ढीले युग्मन को प्रोत्साहित करेगा। इसके कई फायदे हैं लेकिन लगभग कोई कमियां नहीं हैं। मैं चाहता हूं कि अधिक घटकों को इस तरह से डिजाइन किया जाएगा!


6
यह सही उत्तर है, और मैंने इसे उतारा है, लेकिन आप कुछ फायदे बताकर इसे बेहतर बना सकते हैं। मुझे लगता है कि ओपी की वृत्ति उसे बता रही है कि एक समस्या कुछ और है ... वह यह है कि VideoCompressor वास्तव में एक इंटरफ़ेस है। Mp4VideoCompressor एक वर्ग है और किसी VideoSplitter के लिए कोड को कॉपी किए बिना किसी अन्य VideoCompressor के साथ विनिमेय होना चाहिए।
पीडीआर

1
क्षमा करें, लेकिन आप गलत हैं। एकल विधि वाला एक वर्ग सिर्फ एक स्टैंडअलोन फ़ंक्शन होना चाहिए।
मील्स राउत

3
@ माइल्सराउट: आपकी टिप्पणी आपको इस सवाल का गलत अर्थ दिखाती है - ओपी ने एक विधि के साथ एक वर्ग के बारे में लिखा था, न कि एक विधि के साथ (और वह वास्तव में कई निजी तरीकों के साथ एक वर्ग का मतलब था, जैसा कि उसने हमें यहां एक टिप्पणी में बताया था)।
डॉक्टर ब्राउन

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

2
@ और: सवाल यह था कि "यह एक समस्या है" और "यह एक विशिष्ट OO परिभाषा के अनुरूप नहीं है"। इसके अलावा, इस सवाल का कोई मतलब नहीं है कि ओपी का मतलब है, बिना राज्य वाली कक्षाएं।
डॉक्टर ब्राउन

26

यह अब ऑब्जेक्ट ओरिएंटेड नहीं है। क्योंकि वे वर्ग किसी भी चीज़ का प्रतिनिधित्व नहीं करते हैं, वे केवल कार्यों के लिए बर्तन हैं।

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

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

एक मामला है जब आपको एकल सार्वजनिक विधि के साथ वर्ग की आवश्यकता हो सकती है क्योंकि इसे एकल सार्वजनिक विधि के साथ इंटरफ़ेस को लागू करना होगा। पर्यवेक्षक पैटर्न या निर्भरता इंजेक्शन या जो कुछ भी हो, उसके लिए रहें। यहाँ यह फिर से भाषा पर निर्भर करता है। जिन भाषाओं में प्रथम श्रेणी के फंक्शंस (C ++ ( std::functionया टेम्प्लेट पैरामीटर)), C # (डेलिगेट), पायथन, पर्ल, रूबी ( proc), लिस्प, हास्केल, ...) ये पैटर्न फ़ंक्शन प्रकारों का उपयोग करते हैं और कक्षाओं की आवश्यकता नहीं होती है। जावा (अभी तक, संस्करण 8 में होगा) में फ़ंक्शन प्रकार नहीं हैं, इसलिए आप एकल विधि इंटरफेस और इसी एकल विधि वर्गों का उपयोग करते हैं।

बेशक मैं एकल विशाल समारोह लिखने की वकालत नहीं कर रहा हूँ। इसमें निजी सबरूटीन्स होने चाहिए, लेकिन वे कार्यान्वयन फ़ाइल (C-++ में फ़ाइल-स्तरीय स्थैतिक या अनाम नामस्थान) या किसी निजी सहायक वर्ग में निजी हो सकते हैं, जो केवल सार्वजनिक फ़ंक्शन के अंदर ही चालू है ( डेटा संग्रहीत करने के लिए या नहीं? )।


12
"जब यह नहीं है तो यह एक वर्ग का दिखावा क्यों करता है।" एक नि: शुल्क समारोह के बजाय एक वस्तु होने से राज्य और उपप्रकार की अनुमति मिलती है। यह एक ऐसी दुनिया में मूल्यवान साबित हो सकता है जहां आवश्यकताएं बदलती हैं। अभी या बाद में वीडियो संपीड़न सेटिंग्स के साथ खेलने या वैकल्पिक संपीड़न एल्गोरिदम प्रदान करने की आवश्यकता है। इससे पहले कि शब्द "वर्ग" बस हमें बताता है कि यह फ़ंक्शन एक स्पष्ट जिम्मेदारी के साथ आसानी से एक्स्टेंसिबल और विनिमेय सॉफ्टवेयर मॉड्यूल से संबंधित है। क्या ऐसा नहीं है कि वास्तव में OO का उद्देश्य क्या है?
29:05

1
ठीक है, अगर यह केवल एक सार्वजनिक विधि है (और किसी भी संरक्षित लोगों को लगाने का प्रकार), यह वास्तव में बढ़ाया नहीं जा सकता है। निश्चित रूप से पैकिंग संपीड़न पैरामीटर समझ में आ सकता है कि किस मामले में यह फ़ंक्शन ऑब्जेक्ट बन जाता है (कुछ भाषाओं में उनके लिए अलग समर्थन है, कुछ नहीं)।
Jan Hudec

3
यह ऑब्जेक्ट और फ़ंक्शंस के बीच एक मूलभूत संबंध है: एक फ़ंक्शन किसी ऑब्जेक्ट के लिए एक एकल विधि और कोई फ़ील्ड नहीं है। एक बंद करने के लिए एक एकल विधि और कुछ क्षेत्रों के साथ एक वस्तु के लिए isomorphic है। एक चयनकर्ता फ़ंक्शन कई कार्यों में से एक को लौटाता है जो सभी चर के एक ही सेट पर बंद होता है जो किसी वस्तु के लिए आइसोमोर्फिक है। (वास्तव में, यह है कि कैसे वस्तुओं को जावास्क्रिप्ट में एन्कोड किया जाता है, सिवाय इसके कि आप चयनकर्ता फ़ंक्शन के बजाय एक शब्दकोश डेटा संरचना का उपयोग करते हैं।)
Jörg W Mittag

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

2
@ घोषी: हां, मैं समझती हूं। मैंने कभी दावा नहीं किया कि एक कार्यात्मक दृष्टिकोण भी काम नहीं करेगा। हालाँकि, यह स्पष्ट रूप से विषय नहीं है। एक वीडियो कंप्रेसर या एक वीडियो ट्रांसमीटर या जो अभी भी एक वस्तु के लिए पूरी तरह से वैध उम्मीदवार है।
आते हैं

13

किसी दिए गए तरीके को समर्पित वर्ग में निकालने के कारण हो सकते हैं। उन कारणों में से एक निर्भरता इंजेक्शन की अनुमति देना है।

कल्पना कीजिए कि आपके पास एक वर्ग है जिसे VideoExporterअंततः, एक वीडियो को संपीड़ित करने में सक्षम होना चाहिए। एक साफ तरीका एक इंटरफ़ेस होगा:

interface IVideoCompressor
{
    Stream compress(Video video);
}

जिसे इस तरह लागू किया जाएगा:

class MpegVideoCompressor : IVideoCompressor
{
    // ...
}

class FlashVideoCompressor : IVideoCompressor
{
    // ...
}

और इस तरह से इस्तेमाल किया:

class VideoExporter
{
    // ...
    void export(Destination destination, IVideoCompressor compressor)
    {
        // ...
        destination = compressor(this.source);
        // ...
    }
    // ...
}

एक बुरा विकल्प यह होगा कि VideoExporterजिसके पास बहुत सारी सार्वजनिक विधियां हों और जिसमें कंप्रेसिंग सहित सभी काम हों। यह जल्दी से एक रखरखाव दुःस्वप्न बन जाएगा, जिससे अन्य वीडियो प्रारूपों के लिए समर्थन जोड़ना मुश्किल हो जाएगा।


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

2
@DocBrown: निजी तरीके इस सवाल के लिए प्रासंगिक नहीं हैं। उन्हें आंतरिक सहायक वर्ग या जो भी हो, पर रखा जा सकता है।
Jan Hudec

2
@JanHudec: वर्तमान में पाठ "एक बुरा विकल्प एक VideoExporter होगा जो बहुत सारे तरीके हैं" - लेकिन यह होना चाहिए "एक बुरा विकल्प एक VideoExporter होगा जिसमें बहुत सारे सार्वजनिक तरीके हों"।
डॉक्टर ब्राउन

@DocBrown: यहां सहमत हैं।
Jan Hudec

2
@DocBrown: आपकी टिप्पणी के लिए धन्यवाद। मैंने अपना उत्तर संपादित किया। मूल रूप से, मैंने सोचा था कि यह मान लिया गया था कि सवाल (और इसलिए मेरा जवाब) केवल सार्वजनिक तरीकों के बारे में है। ऐसा प्रतीत होता है कि यह स्पष्ट नहीं है।
आर्सेनी मूरज़ेंको

6

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

यदि आप वास्तव में इन फ़ेक्स-फ़ंक्शंस को पास नहीं कर रहे हैं, तो आप बस एक निःशुल्क / स्थिर फ़ंक्शन चाहते हैं।


1
जावा 8 के बाद से, आपके पास लैम्ब्डा है, इसलिए आप बहुत अधिक कार्य कर सकते हैं।
सिल्वियू बर्किया

उचित बिंदु, लेकिन यह आधिकारिक तौर पर थोड़ी देर के लिए जारी नहीं किया जाएगा, और कुछ कार्यस्थल नए संस्करणों में जाने के लिए धीमी हैं।
डोभाल

रिलीज की तारीख मार्च में है। इसके अलावा, EAP बिल्ड JDK 8 के लिए बहुत लोकप्रिय थे :)
सिल्वू बर्किया

हालाँकि, जावा 8 लैम्ब्डा केवल एक सार्वजनिक विधि के साथ वस्तुओं को परिभाषित करने के लिए एक संक्षिप्त तरीका है, बॉयलरप्लेट कोड को थोड़ा सा बचाने के अलावा, वे यहां बिल्कुल भी कोई फर्क नहीं करते हैं।
जूल्स

5

मुझे पता है कि मुझे पार्टी में देर हो रही है लेकिन जैसा कि हर एक को यह इंगित करने में चूक हुई है:

यह एक अच्छी तरह से ज्ञात डिज़ाइन पैटर्न है जिसे रणनीति पैटर्न कहा जाता है ।

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

उदाहरण के लिए इस मामले में आप interface VideoCompressorऔर फिर उदाहरण के लिए कई वैकल्पिक कार्यान्वयन हो सकते हैं class H264Compressor implements VideoCompressorऔर class XVidCompressor implements VideoCompressor। ओपी से यह स्पष्ट नहीं है कि इसमें एक इंटरफ़ेस शामिल है, भले ही वहाँ नहीं है, यह बस हो सकता है कि मूल लेखक ने रणनीति पैटर्न को लागू करने के लिए दरवाजा खुला छोड़ दिया हो, यदि आवश्यक हो। जो अपने आप में अच्छी डिजाइन भी है।

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

कई मामलों में रणनीति पैटर्न का परिणाम केवल एक doStuff(...)विधि के साथ इंटरफ़ेस कक्षाओं (जैसा कि आप दिखा रहे हैं) में होता है ।


1
public interface IVideoProcessor
{
   void Split();

   void Compress();

   void Index();
}

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

दूसरी ओर, यदि विभाजित करना, संपीड़ित करना और अनुक्रमण किसी भी तरह से संबंधित नहीं था, तो मैं उन्हें अलग-अलग घटकों के रूप में रखूंगा।


जैसा कि इन कार्यों में से प्रत्येक को बदलने की आवश्यकता कुछ अलग है, मैं तर्क देता हूं कि उन्हें इस तरह से एक साथ रखना एसआरपी का उल्लंघन करता है।
जूल्स

0

यह एक समस्या है - आप डेटा के बजाय डिजाइन के कार्यात्मक पहलू से काम कर रहे हैं। आपके पास वास्तव में 3 स्टैंडअलोन फ़ंक्शन हैं जो OO-ified किए गए हैं।

उदाहरण के लिए, आपके पास एक VideoCompressor वर्ग है। आप वीडियो को संपीड़ित करने के लिए डिज़ाइन किए गए वर्ग के साथ क्यों काम कर रहे हैं - आपके पास इस प्रकार के प्रत्येक वीडियो में मौजूद (वीडियो) डेटा को संक्षिप्त करने के लिए वीडियो विधियों के साथ वीडियो क्लास क्यों नहीं है?

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

संपादित करें:

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

string mystring("Hello"); 
mystring.concat("World");

लेकिन ओपी चाहता है कि वह इस तरह काम करे:

string mystring();
string result = mystring.concat("Hello", "World");

अब ऐसी जगहें हैं जहां संबंधित कार्यों का एक संग्रह रखने के लिए एक वर्ग का उपयोग किया जा सकता है, लेकिन वह ओओ नहीं है, अपने कोडबेस को बेहतर ढंग से प्रबंधित करने में मदद करने के लिए भाषा की ओओ सुविधाओं का उपयोग करने का एक आसान तरीका है, लेकिन यह किसी भी तरह से नहीं है "ओओ डिजाइन" का। ऐसे मामलों में ऑब्जेक्ट पूरी तरह से कृत्रिम है, बस इस तरह से उपयोग किया जाता है क्योंकि भाषा इस तरह की समस्या को प्रबंधित करने के लिए कुछ भी बेहतर प्रदान नहीं करती है। जैसे। C # जैसी भाषाओं में आप इस कार्यक्षमता को प्रदान करने के लिए एक स्थिर वर्ग का उपयोग करेंगे - यह वर्ग तंत्र को पुन: उपयोग करता है, लेकिन अब आपको केवल इस पर विधियों को कॉल करने के लिए किसी ऑब्जेक्ट को तुरंत करने की आवश्यकता नहीं है। आप उन तरीकों के साथ अंत करते हैं, string.IsNullOrEmpty(mystring)जो मुझे लगता है कि तुलना में खराब है mystring.isNullOrEmpty()

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


9
-1, मैं पूरी तरह से असहमत हूं। शुरुआती OO डिज़ाइन केवल डेटा ऑब्जेक्ट्स के साथ काम करता है जैसे Videoऔर कार्यक्षमता के साथ ऐसी कक्षाओं को ओवरब्लो करता है, जो अक्सर प्रति क्लास> 10K LOC के साथ गन्दा कोड में समाप्त होता है। उन्नत OO डिज़ाइन छोटी इकाइयों की तरह कार्यक्षमता को तोड़ता है VideoCompressor(और एक Videoवर्ग को केवल एक डेटा वर्ग या एक मुखौटा होने देता है VideoCompressor)।
डॉक ब्राउन

5
@DocBrown: जिस बिंदु पर यह अब एक वस्तु उन्मुख डिजाइन नहीं है, क्योंकि यह VideoCompressorएक वस्तु का प्रतिनिधित्व नहीं करता है । इसमें कुछ भी गलत नहीं है, बस ऑब्जेक्ट ओरिएंटेड डिज़ाइन की सीमा को दर्शाता है।
जान हुदेक

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

4
@ डॉकब्रॉन ने वास्तव में मेरी चिंता को उजागर किया; मेरे पास वास्तव में एक Videoवर्ग है, लेकिन संपीड़न पद्धति किसी भी तरह से तुच्छ नहीं है, इसलिए मैं वास्तव में इस compressविधि को कई निजी तरीकों में तोड़ दूंगा। यह मेरे प्रश्न के कारण का हिस्सा है, पढ़ने के बाद क्रिया कक्षाएं न बनाएं
yjwong

2
मुझे लगता है कि यह एक है करने के लिए ठीक हो सकता है Videoवर्ग, लेकिन यह किया जाएगा बना एक की VideoCompressor, एक VideoSplitter, और अन्य संबंधित वर्गों, जो अच्छा OO रूप में, अत्यधिक एकजुट अलग अलग वर्गों होना चाहिए।
एरिक किंग

-1

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

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

वैसे, आपने कहा

मैं अपने आप को प्रत्येक वर्ग को तात्कालिक बनाने में लगा हूं

, ये कक्षाएं सेवाओं (और इस प्रकार स्टेटलेस) लगती हैं। क्या आपने उन्हें सिंगल बनाने के बारे में सोचा है?


1
सिंगलटन, आमतौर पर, एंटीपैटर्न होते हैं। एकल देखें : 1995 के बाद से आपके पास ऐसी समस्याएं नहीं थीं जिन्हें आप जानते थे
Jan Hudec

3
बाकी के लिए जबकि इंटरफ़ेस पृथक्करण सिद्धांत एक अच्छा पैटर्न है, यह सवाल कार्यान्वयन के बारे में है, इंटरफेस नहीं है, इसलिए मुझे यकीन नहीं है कि यह प्रासंगिक है।
Jan Hudec

3
मैं इस बारे में चर्चा नहीं करने वाला कि क्या सिंगलटन एक पैटर्न है या एक एंटीपैटर्न है। मैंने इसकी समस्या के लिए एक संभावित समाधान (इसका एक नाम भी है) का सुझाव दिया , यह तय करना उसके ऊपर है कि वह फिट बैठता है या नहीं।
डाइगोमेटासिस

इस बारे में कि आईएसपी प्रासंगिक है या नहीं, ठीक है, सवाल का विषय है "क्या केवल एक ही विधि समस्या वाली कक्षाएं हैं?", इसके विपरीत कई तरीकों के साथ एक वर्ग है, जो एक समस्या बन जाता है जिस क्षण आप एक बनाते हैं? ग्राहक सीधे उस पर निर्भर करते हैं ... बिल्कुल रॉबर्ट मार्टिन के जेरॉक्स उदाहरण ने उसे आईएसपी तैयार करने के लिए लिया।
डाइगोमेटासिस

-1

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

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

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