समानांतर पदानुक्रम - आंशिक रूप से समान, आंशिक रूप से भिन्न


12

वहाँ काफी कुछ इसी तरह के सवाल हैं 1 ,2 ,3 ,4 , लेकिन गैर इस सवाल में बिल्कुल ऐसा लगता है, और न ही समाधान इष्टतम लगते हैं।

यह एक सामान्य ओओपी प्रश्न है, यह मानते हुए कि बहुरूपता, जेनरिक, और मिश्रण उपलब्ध हैं। उपयोग की जाने वाली वास्तविक भाषा OOP जावास्क्रिप्ट (टाइपस्क्रिप्ट) है, लेकिन यह जावा या C ++ में समान समस्या है।

मेरे पास समानांतर श्रेणी की पदानुक्रम हैं, जो कभी-कभी समान व्यवहार (इंटरफ़ेस और कार्यान्वयन) साझा करते हैं, लेकिन कभी-कभी प्रत्येक का अपना 'संरक्षित' व्यवहार होता है। इस तरह चित्रित:

3 समानांतर वर्ग पदानुक्रम, केंद्र स्तंभ सामान्य भागों को दिखाता है, बायां स्तंभ कैनवास पदानुक्रम है और दायां स्तंभ SVG पदानुक्रम दिखाता है

यह केवल दृष्टांत उद्देश्यों के लिए है ; यह वास्तविक वर्ग आरेख नहीं है। इसे पढ़ने के लिए:

  • सामान्य पदानुक्रम (केंद्र) में कुछ भी दोनों कैनवस (बाएं) और एसवीजी (दाएं) पदानुक्रम के बीच साझा किया जाता है। शेयर से मेरा मतलब है कि इंटरफ़ेस और कार्यान्वयन दोनों।
  • केवल बाएं या दाएं स्तंभों पर कुछ भी मतलब है कि पदानुक्रम के लिए विशिष्ट व्यवहार (तरीके और सदस्य)। उदाहरण के लिए:
    • बाएं और दाएं पदानुक्रम दोनों समान सत्यापन तंत्र का उपयोग करते हैं, Viewee.validate()जो सामान्य पदानुक्रम पर एकल विधि ( ) के रूप में दिखाया गया है।
    • केवल कैनवास पदानुक्रम में एक विधि है paint()। यह विधि सभी बच्चों पर पेंट विधि को बुलाती है।
    • एसवीजी पदानुक्रम की addChild()विधि को ओवरराइड करने की आवश्यकता है Composite, लेकिन कैनवास पदानुक्रम के साथ ऐसा नहीं है।
  • दोनों ओर के पदानुक्रमों के निर्माणों को मिश्रित नहीं किया जा सकता है। एक कारखाना यह सुनिश्चित करता है।

समाधान I - छेड़छाड़ के अलावा छेड़छाड़

फाउलर का छेड़ो इनहेरिटेंस यहां काम नहीं करता है, क्योंकि दोनों के बीच कुछ विसंगति है।

समाधान II - मिश्रण

यह केवल वही है जिसके बारे में मैं अभी सोच सकता हूं। दो पदानुक्रम अलग-अलग विकसित होते हैं, लेकिन प्रत्येक स्तर पर कक्षाएं सामान्य वर्ग को मिलाती हैं, जो एक वर्ग पदानुक्रम का हिस्सा नहीं हैं। structuralकांटा छोड़ना , इस तरह दिखेगा:

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

ध्यान दें कि प्रत्येक स्तंभ अपने स्वयं के नामस्थान में होगा, इसलिए वर्ग नाम संघर्ष नहीं करेंगे।

प्रश्न

क्या कोई इस दृष्टिकोण के साथ दोष देख सकता है? क्या कोई बेहतर उपाय सोच सकता है?


परिशिष्ट

यहां कुछ नमूना कोड दिए गए हैं कि यह कैसे उपयोग किया जाना है। नाम svgस्थान के साथ प्रतिस्थापित किया जा सकता है canvas:

var iView        = document.getElementById( 'view' ),
    iKandinsky   = new svg.Kandinsky(),
    iEpigone     = new svg.Epigone(),
    iTonyBlair   = new svg.TonyBlair( iView, iKandinsky ),
    iLayer       = new svg.Layer(),
    iZoomer      = new svg.Zoomer(),
    iFace        = new svg.Rectangle( new Rect( 20, 20, 100, 60) ),
    iEyeL        = new svg.Rectangle( new Rect( 20, 20, 20, 20) ),
    iEyeR        = new svg.Rectangle( new Rect( 60, 20, 20, 20) );

iKandinsky.setContext( iTonyBlair.canvas.getContext( '2d' ) );
iEpigone.setContext( iTonyBlair.canvas.getContext( '2d' ) );

iFace.addChildren( iEyeL, iEyeR );
iZoomer.setZoom( new Point( 2, 2 ) );
iZoomer.addChild( iFace );
iLayer.addChild( iZoomer );
iTonyBlair.setContent( iLayer );

अनिवार्य रूप से, रन-टाइम क्लाइंट में व्यूई उपवर्गों के पदानुक्रम की रचना करते हैं; इस तरह:

एक छवि जिसमें वस्तुओं का एक पदानुक्रम दिखाया गया है जैसे परत, परत, स्क्रोलर, आदि।

कहें कि ये सभी दृश्य कैनवास के पदानुक्रम से हैं, वे paint()प्रत्येक दृश्य पर पदानुक्रम को कॉल करके प्रस्तुत कर सकते हैं । यदि वे svg पदानुक्रम से हैं, तो दर्शकों को पता है कि खुद को DOM से कैसे जोड़ा जाए, लेकिन वहाँ कोई ट्रावेल नहीं है paint()



शायद पूर्ण विशेषताओं वाले डेकोरेटर डिज़ाइन पैटर्न (Erich Gamma et als, Design Patterns) आज़माएँ?
जोन

क्या देखने वाला है? संज्ञा के रूप में "समानांतर" का क्या अर्थ है (विशेषण के विपरीत)?
ट्यूलेंस कोरडोवा

क्या आपके पास कई विरासत हैं?
ट्यूलेंस कोर्डोवा

क्या कैनवस या एसवीजी कक्षाओं में अतिरिक्त राज्य या डेटा होता है जो सामान्य नहीं है? आप कक्षाओं का उपयोग कैसे करते हैं? क्या आप कुछ उदाहरण कोड दिखाते हुए दिखा सकते हैं कि इन खोज का उपयोग कैसे किया जा सकता है?
०१०

जवाबों:


5

दूसरा दृष्टिकोण इंटरफ़ेस अलगाव सिद्धांत का पालन करते हुए इंटरफेस को बेहतर ढंग से अलग करता है।

हालाँकि, मैं एक पेंटेबल इंटरफ़ेस जोड़ूँगा।

मैं कुछ नाम भी बदलूंगा। भ्रम पैदा करने की आवश्यकता नहीं:

// common

public interface IComposite {
    public void addChild(Composite e);
}

public interface IViewee extends IComposite{
    public void validate();
    public List<IBound> getAbsoluteBouns();
}

public interface IVisual {
    public List<IBound> getBounds();
}

public interface IRec {
}

public interface IPaintable {
    public void paint();
}

// canvas

public interface ICanvasViewee extends IViewee, IPaintable {
}

public interface ICanvasVisual extends IViewee, IVisual {
}

public interface ICanvasRect extends ICanvasVisual, IRec {
}


// SVG

public interface ISVGViewee extends IViewee {
    public void element();
}

public interface ISVGVisual extends IVisual, ISVGViewee {
}

public interface ISVGRect extends ISVGVisual, IRect {
}

मुझे लगता है कि इस मामले के लिए इंटरफेस मदद कर सकता है। मैं उन कारणों को जानना चाहूंगा जिनके कारण आपका उत्तर अस्वीकृत हो गया था।
umlcat


@arnaud क्या आप "घातीय इंटरफेस" से मतलब है?
ट्यूलेंस कोर्डोवा

@ user61852 ... ठीक है, चलो यह कहना है कि यह बहुत सारे इंटरफेस है। "घातीय" वास्तव में एक गलत शब्द था, यह "गुणक" की तरह अधिक है। इस अर्थ में कि यदि आपके पास अधिक "पहलू" (समग्र, दृश्य, पेंट करने योग्य ...) और अधिक "तत्व" (कैनवास, svg ...) हैं, तो आप बहुत सारे इंटरफेस के साथ समाप्त होंगे।
डेगनलीज

@arnaud आपके पास एक बिंदु है लेकिन कम से कम एक लचीला डिजाइन पहले से है और ओपी की विरासत के बुरे सपने तब हल होंगे जब आप विस्तार करने के लिए मजबूर महसूस नहीं करेंगे। आप कुछ वर्ग का विस्तार करते हैं यदि आप चाहते हैं और एक आकस्मिक पदानुक्रम द्वारा मजबूर नहीं किया गया है।
ट्यूलेंस कोर्डोवा

3

यह एक सामान्य ओओपी प्रश्न है, यह मानते हुए कि बहुरूपता, जेनरिक, और मिश्रण उपलब्ध हैं। उपयोग की जाने वाली वास्तविक भाषा OOP जावास्क्रिप्ट (टाइपस्क्रिप्ट) है, लेकिन यह जावा या C ++ में समान समस्या है।

यह वास्तव में बिल्कुल सच नहीं है। टाइपस्क्रिप्ट का जावा-अर्थात् संरचनात्मक टाइपिंग पर पर्याप्त लाभ है। आप बतख टाइप किए गए टेम्प्लेट के साथ C ++ में ऐसा ही कुछ कर सकते हैं, लेकिन यह बहुत अधिक प्रयास है।

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

यह आपको वास्तव में एक इंटरफ़ेस पदानुक्रम को परिभाषित करने और यह परिभाषित करने की आवश्यकता से है कि कौन सी कक्षाएं किस इंटरफेस का विस्तार करना चाहिए।

बस प्रत्येक वर्ग को परिभाषित करें और इंटरफेस के बारे में भूल जाएं- संरचनात्मक टाइपिंग इसका ध्यान रखेगी।

उदाहरण के लिए:

class SVGViewee {
    validate() { /* stuff */ }
    addChild(svg: SVG) { /* stuff */ }
}
class CanvasViewee {
    validate() { /* stuff */ }
    paint() { /* stuff */ }
}
interface SVG {
    addChild: { (svg: SVG): void };
}
f(viewee: { validate: { (): boolean }; }) {
    viewee.validate();
}
g(svg: SVG) {
    svg.addChild(svg);
}
h(canvas: { paint: { (): void }; }) {
    canvas.paint();
}
f(SVGViewee());
f(CanvasViewee());
g(SVGViewee());
h(CanvasViewee());

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

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


यह आशाजनक लगता है, लेकिन मैं वास्तव में प्रस्ताव को समझ नहीं पाया (क्षमा करें, संभवतः बहुत अधिक ओओपी पूर्वाग्रह है)। शायद आप कुछ कोड उदाहरण साझा कर सकते हैं? उदाहरण के लिए, दोनों svg.Viewee और कैनवस.दृश्य को एक validate()विधि की आवश्यकता है (जिसका कार्यान्वयन दोनों के लिए समान है); उसके बाद केवल svg.Viewee को addChild () को ओवरराइड करने की आवश्यकता होती है , जबकि केवल कैनवस पर दृश्य की आवश्यकता होती है ( सभी बच्चों पर पेंट () जिसे पेंट कहते हैं ) - जो कि आधार समग्र वर्ग के सदस्य हैं )। इसलिए मैं वास्तव में संरचनात्मक टाइपिंग के साथ इसकी कल्पना नहीं कर सकता।
22

आप चीजों के एक पूरे समूह पर विचार कर रहे हैं जो इस मामले में पूरी तरह से मायने नहीं रखते हैं।
डेडएमजी

तो मुझे शायद इसका जवाब बिल्कुल नहीं मिला। अच्छा होगा यदि आप विस्तृत करें।
इज़्हाकी

मैंने एक संपादन किया। लब्बोलुआब यह है कि आधार वर्ग बिल्कुल अप्रासंगिक हैं और कोई भी उनकी परवाह नहीं करता है। वे केवल एक कार्यान्वयन विवरण हैं।
डेडएमजैन

1
ठीक। यह समझ में आने लगा है। ए) मुझे पता है कि बतख टाइपिंग क्या है। बी) मुझे यकीन नहीं है कि इस जवाब में इंटरफेस इतना केंद्रीय क्यों है - सामान्य व्यवहार साझा करने के लिए वर्ग टूटना है, आप अब के लिए इंटरफेस को आसानी से अनदेखा कर सकते हैं। ग) अपने उदाहरण में कहो SVGViewee.addChild(), लेकिन CanvasVieweeयह भी एक ही सुविधा की जरूरत है। तो मुझे समझ में आता है कि दोनों समग्र से निहित है?
इज़्हाकी

3

त्वरित अवलोकन

समाधान 3: "समानांतर श्रेणी पदानुक्रम" सॉफ़्टवेयर डिज़ाइन पैटर्न आपका मित्र है।

लंबा विस्तारित उत्तर

आपका डिज़ाइन सही है। इसे अनुकूलित किया जा सकता है, कुछ वर्गों या सदस्यों को हटाया जा सकता है, लेकिन, "समानांतर पदानुक्रम" विचार आप एक समस्या को हल करने के लिए आवेदन कर रहे हैं।

आमतौर पर नियंत्रण पदानुक्रम में एक ही अवधारणा के साथ कई बार सौदा किया है।

थोड़ी देर के बाद, मैं अन्य समान विकासकर्ताओं को एक ही समाधान करना चाहता हूं, जिसे कभी-कभी "समानांतर पदानुक्रम" डिज़ाइन पैटर्न या "दोहरी पदानुक्रम" डिज़ाइन पैटर्न कहा जाता है।

(१) क्या आपने कभी एकल वर्ग को कक्षाओं के एकल पदानुक्रम में विभाजित किया है?

(२) क्या आपने कभी एकल वर्ग को कई वर्गों में विभाजित किया है, बिना पदानुक्रम के?

यदि आपने इन पिछले समाधानों को अलग से लागू किया है, तो वे कुछ समस्याओं को हल करने का एक तरीका हैं।

लेकिन, क्या होगा अगर हम इन दो समाधानों को एक साथ जोड़ते हैं?

उन्हें मिलाएं, और, आपको यह "डिज़ाइन पैटर्न" मिलेगा।

कार्यान्वयन

अब, अपने मामले में "समानांतर श्रेणी पदानुक्रम" सॉफ़्टवेयर डिज़ाइन पैटर्न लागू करें।

आपके पास वर्तमान में कक्षाओं के 2 या अधिक स्वतंत्र पदानुक्रम हैं, जो बहुत समान हैं, समान संघ या purpouse हैं, समान गुण या विधियाँ हैं।

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

तो, आपकी पदानुक्रम इस आकृति के समान हैं, लेकिन, फिर भी, एक से अधिक हैं:

................................................
...............+----------------+...............
...............|     Common::   |...............
...............|    Composite   |...............
...............+----------------+...............
...............|      ...       |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
...............+-------+--------+...............
...............|     Common::   |...............
...............|     Viewee     |...............
...............+----------------+...............
...............|      ...       |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Common::   |........|     Common::   |..
..|     Visual     |........|   Structural   |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 1

इसमें, अभी तक प्रमाणित नहीं किया गया है, डिज़ाइन पैटर्न, SEVERAL SIMILAR HIERARCHIES, MERGED, INTO A SINGLE HIERARCHY, और प्रत्येक साझा या सामान्य वर्ग को उपवर्ग द्वारा विस्तारित किया गया है।

ध्यान दें, यह समाधान जटिल है, क्योंकि आप पहले से ही कई पदानुक्रमों के साथ काम कर रहे हैं, इसलिए एक जटिल परिदृश्य है।

1 रूट क्लास

प्रत्येक पदानुक्रम में एक साझा "रूट" वर्ग है।

आपके मामले में, प्रत्येक पदानुक्रम के लिए एक स्वतंत्र "समग्र" वर्ग है, जिसमें कुछ समान गुण और कुछ समान विधियां हो सकती हैं।

उन सदस्यों में से कुछ को विलय किया जा सकता है, उन सदस्यों में से कुछ को विलय नहीं किया जा सकता है।

इसलिए, एक डेवलपर क्या कर सकता है, एक आधार जड़ वर्ग बनाना है, और प्रत्येक पदानुक्रम के बराबर मामले को उप-वर्ग करना है।

चित्र 2 में, आप इस वर्ग के लिए एक आरेख देख सकते हैं, जिसमें प्रत्येक वर्ग, इसे नाम स्थान रखता है।

सदस्यों, अब तक छोड़े गए हैं।

................................................
...............+-------+--------+...............
...............|     Common::   |...............
...............|    Composite   |...............
...............+----------------+...............
...............|      ...       |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Canvas::   |........|      SVG::     |..
..|    Composite   |........|    Composite   |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 2

जैसा कि, आप ध्यान दें, प्रत्येक "कम्पोजिट" क्लैस अब एक अलग पदानुक्रम में नहीं है, लेकिन, एक साझा या सामान्य पदानुक्रम में विलय हो गया है।

फिर, सदस्यों को जोड़ते हैं, जो समान हैं, उन्हें सुपरक्लास में स्थानांतरित किया जा सकता है, और जो अलग-अलग हैं, प्रत्येक आधार वर्ग के लिए।

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

................................................
.............+--------------------+.............
.............|       Common::     |.............
.............|      Composite     |.............
.............+--------------------+.............
.............| [+] void AddChild()|.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Canvas::   |........|      SVG::     |..
..|    Composite   |........|    Composite   |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 3

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

2 उपवर्ग

आइए पहले आरेख पर वापस जाएं। प्रत्येक "समग्र" वर्ग में, प्रत्येक पदानुक्रम में "व्यूई" उपवर्ग था।

प्रत्येक वर्ग के लिए प्रक्रिया को दोहराया जाता है। चित्र 4 की तुलना में, "कॉमन :: व्यूई" वर्ग "कॉमन :: कम्पोजिट" से नीचे उतरता है, लेकिन, सादगी के लिए, "कॉमन :: कम्पोजिट" क्लास को आरेख से हटा दिया जाता है।

................................................
.............+--------------------+.............
.............|       Common::     |.............
.............|       Viewee       |.............
.............+--------------------+.............
.............|        ...         |.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Canvas::   |........|      SVG::     |..
..|     Viewee     |........|     Viewee     |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 4

आप ध्यान दें, कि "कैनवस :: सीवी" और "एसवीजी :: व्यूई", अपने संबंधित "समग्र" से नहीं उतरता है, लेकिन, आम "कॉमन :: व्यूई" के बजाय।

अब आप सदस्यों को जोड़ सकते हैं।

......................................................
.........+------------------------------+.............
.........|            Common::          |.............
.........|            Viewee            |.............
.........+------------------------------+.............
.........| [+] bool Validate()          |.............
.........| [+] Rect GetAbsoluteBounds() |.............
.........+-------------+----------------+.............
.......................|..............................
.......................^..............................
....................../.\.............................
.....................+-+-+............................
.......................|..............................
..........+------------+----------------+.............
..........|.............................|.............
..+-------+---------+........+----------+----------+..
..|      Canvas::   |........|         SVG::       |..
..|      Viewee     |........|        Viewee       |..
..+-----------------+........+---------------------+..
..|                 |........| [+] Viewee Element  |..
..+-----------------+........+---------------------+..
..| [+] void Paint()|........| [+] void addChild() |..
..+-----------------+........+---------------------+..
......................................................

Figure 5

3 प्रक्रिया को दोहराएं

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

4 3 डी पदानुक्रम आरेख

आप एक 3 डी आरेख की तरह खत्म हो जाएगा, कई परतों के साथ, शीर्ष परत, "आम" पदानुक्रम है और नीचे की परतों, प्रत्येक अतिरिक्त पदानुक्रम है।

आपकी मूल स्वतंत्र श्रेणी पदानुक्रम, जहाँ कुछ इसी के समान है (चित्र 6):

.................................................
..+-----------------+.......+-----------------+..
..|      Common::   |.......|       SVG::     |..
..|     Composite   |.......|     Composite   |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..|      Common::   |.......|       SVG::     |..
..|      Viewee     |.......|      Viewee     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..|      Common::   |.......|       SVG::     |..
..|      Visual     |.......|      Visual     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..|      Common::   |.......|       SVG::     |..
..|       Rect      |.......|       Rect      |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+-----------------+.......+-----------------+..
.................................................

Figure 6

ध्यान दें कि कुछ कक्षाएं छोड़ी गई हैं, और पूरे "कैनवस" पदानुक्रम को सरलता से छोड़ दिया गया है।

अंतिम एकीकृत वर्ग पदानुक्रम कुछ इस तरह हो सकता है:

.................................................
..+-----------------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|     Composite   |...\+..|     Composite   |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|      Viewee     |...\+..|      Viewee     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|      Visual     |...\+..|      Visual     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|       Rect      |...\+..|       Rect      |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+-----------------+.......+-----------------+..
.................................................
Figure 7

ध्यान दें कि कुछ कक्षाएं छोड़ी गई हैं, और पूरे "कैनवस" वर्ग को सरलता से, लेकिन, "एसवीजी" वर्गों के समान छोड़ दिया जाएगा।

"कॉमन" कक्षाओं को एक 3 डी आरेख की एक परत के रूप में, दूसरी परत में "एसवीजी" कक्षाओं और एक तीसरी परत में "कैनवस" कक्षाओं के रूप में दर्शाया जा सकता है।

जांचें, कि प्रत्येक परत पहले एक से संबंधित है, जिसमें, प्रत्येक वर्ग में "कॉमन" पदानुक्रम का मूल वर्ग है।

कोड कार्यान्वयन के लिए या तो उपयोग करने की आवश्यकता हो सकती है, इंटरफ़ेस विरासत, वर्ग विरासत या "मिश्रण", जो आपके प्रोग्राम की भाषा का समर्थन करता है पर निर्भर करता है।

सारांश

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

मैं "समाधान 1" या "समाधान 2" लागू करने की अनुशंसा नहीं करता हूं।

"समाधान 1" में लागू नहीं होता है, क्योंकि, प्रत्येक मामले में विरासत की आवश्यकता होती है।

"समाधान 2", "मिक्सिंस" लागू किया जा सकता है, लेकिन, कक्षाओं और पदानुक्रमों को डिजाइन करने के बाद।

मिक्सिंस, इंटरफ़ेस-आधारित विरासत या क्लास-आधारित मल्टीपल इनहेरिटेंस के लिए एक विकल्प हैं।

मेरे प्रस्तावित, समाधान 3, को कभी-कभी "समानांतर पदानुक्रम" डिज़ाइन पैटर्न या "दोहरी पदानुक्रम" डिज़ाइन पैटर्न कहा जाता है।

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

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


बहुत गहन उत्तर के लिए धन्यवाद। मुझे लगता है कि मैंने इसे ठीक से समझा है, इसलिए मुझे यह पूछना चाहिए: canvas.vieweeऔर इसके सभी वंशजों को एक विधि की आवश्यकता है paint()। न तो commonहै और न ही svgकक्षाएं इसकी आवश्यकता है। लेकिन आपके समाधान में, पदानुक्रम मेरे समाधान में है या commonनहीं जैसा कि 2. तो क्या वास्तव में सभी उपवर्गों में समाप्त होता है अगर वहाँ कोई विरासत नहीं है? canvassvgpaint()canvas.viewee
इजाकी

@Izhaki क्षमा करें यदि मेरे उत्तर में कुछ कीड़े हैं। फिर paint()"कैनवास :: व्यूई" में स्थानांतरित या घोषित किया जाना चाहिए। सामान्य पैटर्न विचार रहता है, लेकिन कुछ सदस्यों को स्थानांतरित करने या बदलने की आवश्यकता हो सकती है।
umlcat 1

ठीक है, तो उपवर्गों को कैसे प्राप्त होता है, अगर कोई भी इससे प्राप्त नहीं करता है canvas::viewee?
इजाकी

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

1

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

यह पैटर्न वंशानुगत रिश्तों के नेटवर्क का वर्णन करता है जिसकी आवश्यकता तब होती है जब किसी दिए गए पदानुक्रम को अपनी संपूर्णता में, किसी अन्य वर्ग के लिए अनुकूलित किया जाना चाहिए।

और आरेख प्रदान किया गया:

दो समानांतर विरासत संरचनाओं के साथ एक वर्ग आरेख, जहां दाईं ओर प्रत्येक वर्ग भी बाईं ओर अपने जुड़वां वर्ग से लगभग निहित है।  बायां पदानुक्रम भी पूरी तरह से आभासी विरासत पर आधारित है

यद्यपि समाधान 2 में वर्चुअल इनहेरिटेंस नहीं है, यह सीढ़ी मार्ग से स्वर्ग पैटर्न के अनुरूप है । इस प्रकार समाधान 2 इस समस्या के लिए उचित लगता है।

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