कम्पोजीशन ओवर इनहेरिटेंस

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग ऊप में इनहेरिटेंस पर रचना सिद्धांत या सम्मिश्र पुनः प्रयोग सिद्धांत के रूप में होता है तथा क्लासेस को बहुरूपता कंप्यूटर विज्ञान व्यवहार और कोड का पुन: उपयोग करना चाहिए तथा उनकी संरचना द्वारा अन्य क्लासेस के उदाहरण देना चाहिए जो किसी आधार या पैरेंट क्लास से प्राप्त इनहेरिटेंस कंप्यूटर विज्ञान के अतिरिक्त वांछित कार्यकार्यात्मकता को कार्यान्वित करते हैं। यह ऊप का प्रायः सिद्धांत है, जिसमे कि प्रभावशाली पुस्तक डिजाइन पैटर्न्स 1994 में हुआ था।

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

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

इनहेरिटेंस
सी ++ में एक उदाहरण इस प्रकार है,

class Object

{ public: virtual void update { // no-op } virtual void draw { // no-op } virtual void collide(Object objects[]) { // no-op } }; class Visible : public Object { Model* model; public: virtual void draw override { // code to draw a model at the position of this object } }; class Solid : public Object { public: virtual void collide(Object objects[]) override { // code to check for and react to collisions with other objects } }; class Movablej: public Object { public: virtual void update override { // code to update the position of this object } };

फिर, मान लीजिए कि हमारे पास ये काँक्रीट क्लास इस प्रकार है

ध्यान दें कि मल्टीपल इनहेरिटेंस खतरनाक रूप में होते है, यदि इसे सावधानी से प्रयुक्त नहीं किया गया क्योंकि इससे मल्टीपल इनहेरिटेंस डायमंड की समस्या हो सकती है। इसका एक समाधान यह है कि प्रत्येक आवश्यक संयोजन के लिए विजिबल एंड सॉलिड विजिबल एंड मूवेबल विजिबल एंड सॉलिड एंड मूवेबल इत्यादि जैसी क्लासेस बनाई जाएं चूंकि, यह बड़ी मात्रा में दोहराव वाले कोड की ओर ले जाता है। C ++ मल्टीपल इनहेरिटेंस की डायमंड प्रॉब्लम को हल करने के लिए वर्चुअल इनहेरिटेंस का उपयोग करता है।
 * क्लास प्लेयर - जो सॉलिड, मूवेबल और विजिबल है
 * क्लास क्लाउड - जो मूववेबल और दृश्यमान रूप में होती है, लेकिन ठोस नहीं होती है
 * क्लास बिल्डिंग - जो सॉलिड और विजिबल रूप में होती है, लेकिन मूवेबल नहीं होती है
 * क्लास ट्रैप - जो ठोस रूप में होती है, लेकिन न तो दिखाई देती है और न ही चल सकती है

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

विजिबिलिटी डेलिगेट नामक एक एब्स्ट्रक्ट क्लास का परिचय उपवर्गों के साथ नॉट विजिबल एंड विजिबल के रूप में होता है, जो किसी वस्तु को खींचने का एक साधन प्रदान करता है

class VisibilityDelegate

{ public: virtual void draw = 0; }; class NotVisibles: public VisibilityDelegate { public: virtual void draw override { // no-op } }; class Visiblec: public VisibilityDelegate { public: virtual void draw override { // code to draw a model at the position of this object } }; अपडेट डेलिगेट नामक एक सार वर्ग का परिचय उपवर्गों के साथ मूववेबल और मूववेबल नहीं के रूप में होती है, जो किसी वस्तु को स्थानांतरित करने का साधन प्रदान करती है

class UpdateDelegate

{ public: virtual void update = 0; }; class NotMovablev: public UpdateDelegate { public: virtual void update override { // no-op } }; class Movablec: public UpdateDelegate { public: virtual void update override { // code to update the position of this object } }; संघट्ट डेलिगेट नामक एक एब्स्ट्रक्ट क्लास का परिचय उपवर्गों ठोस और ठोस नहीं के साथ करते है, जो किसी वस्तु से टकराने का साधन प्रदान करता है class CollisionDelegate

{ public: virtual void collide(Object objects[]) = 0; }; class NotSolidS: public CollisionDelegate { public: virtual void collide(Object objects[]) override { // no-op } }; class Solid : public CollisionDelegate { public: virtual void collide(Object objects[]) override { // code to check for and react to collisions with other objects } };

नामक एक अमूर्त क्लास का परिचय दें UpdateDelegate, उपक्लासेस के साथ NotMovable और Movable, जो किसी वस्तु को स्थानांतरित करने का साधन प्रदान करता है:

अंत में, सदस्यों के साथ ऑब्जेक्ट नामक क्लास का परिचय देते है, यदि इसकी दृश्यता को नियंत्रित करने के लिए एक अद्यतन प्रतिनिधि का उपयोग करके एक दृश्यता प्रतिनिधि की गतिशीलता का उपयोग किया जाता है और संघट्ट प्रतिनिधि का उपयोग करके ठोसता का उपयोग किया जाता है। इस वर्ग में ऐसी विधियाँ होती है, जो इसके सदस्यों को सौंपती हैं। जैसे अपडेट केवल अपडेट डेलिगेट पर एक कॉल विधि का उपयोग करती है class Object

{ VisibilityDelegate* _v; UpdateDelegate* _u; CollisionDelegate* _c; public: Object(VisibilityDelegate* v, UpdateDelegate* u, CollisionDelegate* c)  : _v(v) , _u(u) , _c(c) {} void update { _u->update; } void draw { _v->draw; } void collide(Object objects[]) { _c->collide(objects); } };

तब कंक्रीट इस रूप में दिखती है, class Player : public Object

{ public: Player : Object(new Visible, new Movable, new Solid) {} // ... }; class Smokea: public Object { public: Smoke k: Object(new Visible, new Movable, new NotSolid) {} // ... };

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

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

कुछ लैंग्वेज, विशेष रूप से गो (प्रोग्रामिंग लैंग्वेज ) और रस्ट (प्रोग्रामिंग लैंग्वेज ), विशेष रूप से टाइप कंपोज़िशन का उपयोग करती हैं।

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

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

// Base class

public abstract class Employee { // Properties protected string Name { get; set; } protected int ID { get; set; } protected decimal PayRate { get; set; } protected int HoursWorked { get; } // Get pay for the current pay period public abstract decimal Pay; } // Derived subclass public class HourlyEmployee : Employee { // Get pay for the current pay period public override decimal Pay { // Time worked is in hours return HoursWorked * PayRate; } } // Derived subclass public class SalariedEmployee : Employee { // Get pay for the current pay period public override decimal Pay { // Pay rate is annual salary instead of hourly rate return HoursWorked * PayRate / 2087; } }

कमियों से बचना
ट्रेट्स (कंप्यूटर साइंस), मैक्सिन, प्रकार एम्बेडिंग, या प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) एक्सटेंशन का उपयोग करके इस कमी से बचा जा सकता है।

कुछ लैंग्वेज इसे कम करने के लिए विशिष्ट साधन प्रदान करती हैं


 * सी शार्प (प्रोग्रामिंग लैंग्वेज): संस्करण 8.0 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधि प्रदान करता है, जो बॉडी को इंटरफ़ेस सदस्य को परिभाषित करने की अनुमति देता है।
 * डी (प्रोग्रामिंग लैंग्वेज ) डी एक प्रकार के भीतर स्पष्ट "एलियास यह" घोषणा प्रदान करता है जो इसे प्रत्येक विधि में और एक अन्य निहित प्रकार के सदस्य में अग्रेषित करने की अनुमति देता है।
 * डार्ट (प्रोग्रामिंग लैंग्वेज ) डिफ़ॉल्ट कार्यान्वयन के साथ मिक्सिन प्रदान करता है जिसे साझा किया जा सकता है।
 * गो (प्रोग्रामिंग लैंग्वेज) टाइप एम्बेडिंग अग्रेषण विधियों की आवश्यकता से बचाती है।
 * जावा (प्रोग्रामिंग लैंग्वेज ) संस्करण 8 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधियाँ प्रदान करता है। प्रोजेक्ट लोम्बोक प्रतिनिधिमंडल का समर्थन करता है, डेलिगेट प्रत्यायोजित क्षेत्र से सभी विधियों के नामों और प्रकारों को कॉपी करने और बनाए रखने के अतिरिक्त क्षेत्र पर एनोटेशन प्रदान करता है। * जूलिया (प्रोग्रामिंग लैंग्वेज ) मैक्रोज़ का उपयोग अग्रेषण विधियों को उत्पन्न करने के लिए किया जा सकता है। लेजी जेएल और डेलिगेसन, जैसे कई कार्यान्वयन सम्मलित होती है।
 * कोटलिन (प्रोग्रामिंग लैंग्वेज ) में सिंटैक्स में डेलिगेशन पैटर्न सम्मलित होता है।
 * पीएचपी : लक्षणों (कंप्यूटर विज्ञान) का समर्थन करता है।
 * राकू (प्रोग्रामिंग लैंग्वेज ) : राकू विधि अग्रेषण की सुविधा के लिए एक हैंडल विशेषता प्रदान करता है
 * रस्ट (प्रोग्रामिंग लैंग्वेज) डिफ़ॉल्ट कार्यान्वयन के साथ लक्षण प्रदान करता है।
 * स्काला (प्रोग्रामिंग लैंग्वेज ) संस्करण 3 के बाद से किसी वस्तु के चयनित सदस्यों के लिए उपनामों को परिभाषित करने के लिए एक निर्यात खंड प्रदान करता है।
 * स्विफ्ट (प्रोग्रामिंग लैंग्वेज ) एक्सटेंशन का उपयोग किसी प्रोटोकॉल के डिफ़ॉल्ट कार्यान्वयन को परिभाषित करने के लिए किया जाता है, इसके अतिरिक्त किसी व्यक्तिगत प्रकार के कार्यान्वयन के लिए प्रयोग की जाती है।

अनुभवजन्य अध्ययन
भिन्न -भिन्न आकार के 93 ओपन सोर्स जावा प्रोग्राम के 2013 के एक अध्ययन में पाया गया कि,

"जबकि संरचना (...) के साथ इनहेरिटेंस को बदलने के लिए बहुत बड़ा अवसर महत्वपूर्ण नहीं होता है, इनहेरिटेंस के 2% उपयोग केवल आंतरिक पुन: उपयोग के रूप में हैं और आगे 22% केवल बाहरी या आंतरिक पुन: उपयोग के रूप में होता है। हमारे नतीजे बताते हैं कि कम से कम ओपन सोर्स जावा सॉफ़्टवेयर में इनहेरिटेंस के दुरुपयोग के बारे में चिंता करने की कोई आवश्यकता नहीं होती है, लेकिन वे संरचना बनाम हेरिटेंस के उपयोग के संबंध में प्रश्न को प्रदर्शित करते हैं। यदि संरचना का उपयोग किए जाने पर इनहेरिटेंस का उपयोग करने से जुड़ी महत्वपूर्ण लागतें हैं, तो हमारे परिणाम बताते हैं कि चिंता का कुछ कारण हो सकता है।"

यह भी देखें

 * प्रतिनिधिमंडल पैटर्न
 * लिस्कोव प्रतिस्थापन सिद्धांत
 * ऑब्जेक्ट ओरिएंटेड डिजाइन
 * ऑब्जेक्ट रचना
 * रोल ओरिएंटेड प्रोग्रामिंग
 * स्टेट पैटर्न
 * रणनीति पैटर्न