त्वरित अवलोकन
समाधान 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, को कभी-कभी "समानांतर पदानुक्रम" डिज़ाइन पैटर्न या "दोहरी पदानुक्रम" डिज़ाइन पैटर्न कहा जाता है।
कई डेवलपर्स / डिजाइनर इसके साथ सहमत नहीं होंगे, और मानते हैं कि यह मौजूद नहीं होना चाहिए। लेकिन, मैंने आपके प्रश्न की तरह, गलत और अन्य डेवलपर्स द्वारा समस्याओं के लिए एक सामान्य समाधान के रूप में उपयोग किया है।
एक और गुम बात। आपके पिछले समाधानों में, मुख्य मुद्दा "मिक्सिन्स" या "इंटरफेस" का उपयोग करने के लिए नहीं था, लेकिन, पहले, अपनी कक्षाओं के मॉडल को परिष्कृत करने के लिए, और बाद में एक मौजूदा प्रोग्रामिंग भाषा सुविधा का उपयोग करें।