जब मैं ओओपी कोड लिखता हूं तो मैं सुरुचिपूर्ण वस्तुओं के कुछ अभ्यास लागू करता हूं।
उनमें से एक यह है कि कक्षाएं अंतिम होनी चाहिए। इसका मतलब है कि उन्हें विरासत के माध्यम से नहीं बल्कि केवल संरचना के माध्यम से बढ़ाया जा सकता है।
फायदा सादगी है। मेरा मतलब है कि, इस तरह, प्रत्येक वस्तु को एक संयोजक ब्लॉक के रूप में देखा जाता है। अपने ग्राहकों के लिए क्या दिलचस्पी इसका खुला व्यवहार है। और कुछ नहीं। इसके बजाय, विस्तार के माध्यम से, एक ग्राहक इसे तोड़ सकता है।
उदाहरण के लिए, कोई वस्तु अपनी दो विधियों को आपस में जोड़ सकती है। इसलिए, यदि हम उनमें से एक को विस्तार से बदल सकते हैं तो हम दूसरे को तोड़ सकते हैं। इस कारण से, यह सुनिश्चित करने के लिए, हमें इसके कार्यान्वयन की जांच करनी चाहिए। इस तरह हम विस्तारित और विस्तार के बीच युग्मन बढ़ाते हैं।
दूसरे शब्दों में, अंतिम वर्ग इस विचार को लागू करते हैं कि हमें केवल उजागर व्यवहार की परवाह करनी चाहिए। और अमल का नहीं। फिर भी, इसमें बदलाव की आवश्यकता है कि हम उनके बारे में कैसे तर्क करते हैं। उपनाम पैटर्न इस परिवर्तन के एक पहलू को सरल करता है।
इरादा
उपनाम पैटर्न एक वर्ग को उपवर्ग या संशोधित किए बिना अपनी वस्तुओं का निर्माण करने के तरीके का विस्तार करने की अनुमति देता है।
प्रेरणा
मान लीजिए कि एक अंतिम वर्ग जो कुछ अनिवार्य मापदंडों का उपयोग करके अपनी वस्तुओं का निर्माण करता है। हम इसकी वस्तुओं को बनाने के लिए एक और तरीका कैसे जोड़ सकते हैं? उदाहरण के लिए, हम एक कंस्ट्रक्टर को कैसे जोड़ सकते हैं जो इसके एक या अधिक लापता मापदंडों के लिए डिफ़ॉल्ट मान का उपयोग करता है?
कक्षा में एक और कन्स्ट्रक्टर जोड़ने का एक तरीका हो सकता है। लेकिन यह बात हाथ से निकल सकती है। इसके अलावा, यह संभव नहीं हो सका। उदाहरण के लिए, उपरोक्त अंतिम कक्षा बाहरी पुस्तकालय में हो सकती है।
इस दृष्टिकोण का एक और दोष यह है कि हम अंतिम वर्ग को प्रदूषित कर सकते हैं। उदाहरण के लिए, हमारे पास एक अंतिम वर्ग हो सकता है जो एक JSON दिए गए ऑब्जेक्ट का निर्माण करता है। लेकिन कुछ समय बाद हमें एक्सएमएल भी जोड़ना होगा। जैसा कि आप कल्पना कर सकते हैं कि एक्सएमएल को जेएसओएन में मैप करने के लिए कोड जोड़ना अनिवार्य रूप से उस वर्ग को प्रदूषित करेगा।
हालाँकि, उपनाम पैटर्न अंतिम कक्षाओं तक सीमित नहीं है। उदाहरण के लिए, हमारे पास एक ही पैरामीटर वाले दो कंस्ट्रक्टर नहीं हो सकते हैं, लेकिन अलग-अलग सिमेंटिक हैं।
इस समस्या को हल करने के लिए हम क्लास कोड में स्थिर फ़ैक्टरी विधियों को जोड़ सकते हैं। लेकिन वही उपरोक्त कमियां इस दृष्टिकोण को प्रभावित करती हैं। वह है: यह हाथ से निकल जाता है; यह हमेशा संभव नहीं हो सकता; यह वर्ग को प्रदूषित करेगा।
दोनों समस्याओं के लिए एक बेहतर तरीका वांछित कंस्ट्रक्टर व्यवहार के साथ एक और वर्ग बनाना है। यह वर्ग अपने स्वयं के निर्माण तर्क को समाहित करता है। और यह वास्तविक सृजन सहित अन्य वर्ग को सब कुछ सौंप देगा। यह उपनाम पैटर्न है।
प्रयोज्यता
उपनाम पैटर्न का प्रयोग करें जब:
आपको अंतिम वर्ग के निर्माता को जोड़ने या संशोधित करने की आवश्यकता है;
आप किसी वर्ग के कंस्ट्रक्टर को बिना संशोधित या उपवर्ग के जोड़ना या संशोधित करना चाहते हैं;
आपको एक वर्ग के दो या दो से अधिक कंस्ट्रक्टर की आवश्यकता है, जिसमें बिना किसी संशोधन या उपवर्ग के समान पैरामीटर हों।
संरचना
संरचना सरल है। हमें कम से कम दो वर्ग चाहिए जो समान इंटरफ़ेस लागू करते हैं: एक Alias
और एक Aliased.
प्रतिभागियों
-
AnInterface
एक इंटरफ़ेस घोषित करता है।
-
Aliased
AnInterface
लागू करता है;एक या अधिक कंस्ट्रक्टर्स को उजागर करता है।
-
Alias
-
AnInterface
लागू करता है; - एक या अधिक कंस्ट्रक्टरों को उजागर करता है;
- एक
Aliased
ऑब्जेक्ट का संदर्भ रखता है; - संदर्भित
Aliased
ऑब्जेक्ट को सब कुछ सौंपता है।
-
सहयोग
-
Alias
- अपने स्वयं के नियमों के अनुसार - एकAliased
वस्तु बनाता है और इसका संदर्भ रखता है। फिर यह सब कुछ अलियास को सौंप देता है।
परिणाम
उपनाम पैटर्न के निम्नलिखित परिणाम हैं:
- यह कंस्ट्रक्टर्स को जोड़ना या संशोधित करना आसान बनाता है;
- यह विरासत पर संरचना को बढ़ावा देता है;
- यह कक्षाओं की संख्या बढ़ाता है;
- जब एक आवर्तक निर्माण को बदलने के लिए उपयोग किया जाता है तो यह कोड दोहराव को कम करता है;
- उपनाम कक्षाएं प्रतिनिधि कोड को डुप्लिकेट करती हैं। यदि यह एक समस्या है तो इसे मूल सार उपनाम वर्ग के साथ संपर्क किया जा सकता है।
कार्यान्वयन
उपनाम पैटर्न को लागू करने के लिए आपको चाहिए:
इंटरफ़ेस को परिभाषित करने के लिए;
एक वर्ग के साथ पहले से परिभाषित इंटरफ़ेस को लागू करने के लिए। यह उपनाम होगा;
उपनाम वर्ग के साथ पहले से परिभाषित इंटरफ़ेस को लागू करने के लिए, और आपको इसकी आवश्यकता है:
- एक कंस्ट्रक्टर को परिभाषित करने के लिए जो कुछ जरूरतों के अनुसार एक अलियास्ड ऑब्जेक्ट बनाता है;
- एक निजी आवृत्ति चर जो पहले से निर्मित अलियास्ड ऑब्जेक्ट का संदर्भ देता है;
- उपनामित वस्तु को सब कुछ सौंपने के लिए।
नमूना कोड
नीचे जावा-ईश कोड उपनाम पैटर्न व्यक्त करता है। इस कोड में उपनाम अन्यथा अनिवार्य पैरामीटर के लिए एक डिफ़ॉल्ट मान इंजेक्ट करता है:
interface AnInterface { void aMethod(); Something anotherMethod(); } final class Aliased implements AnInterface { private final A a; private final B b; Aliased(final A a, final B b) { this.a = a; this.b = b; } void aMethod() { // implementation } Something anotherMethod() { // implementation } } final class Alias implements AnInterface { private final Aliased aliased; Alias(final A a) { this( new Aliased( a, new InstanceOfB(...) ) ); } private Alias(final Aliased aliased) { this.aliased = aliased; } void aMethod() { this.aliased.aMethod(); } Something anotherMethod() { return this.aliased.anotherMethod(); } }
संबंधित पैटर्न
कुछ हद तक, उपनाम पैटर्न को वस्तुओं के निर्माण को सजाने के तरीके के रूप में भी देखा जा सकता है। यह दृष्टि विशेष रूप से सच है यदि हम एक वर्ग को एक वस्तु के रूप में देखते हैं जो वस्तुओं को बनाने की जिम्मेदारी है।