इस लेख में, हम देखेंगे कि ये समस्याएं क्या हैं और रचना का उपयोग करके हम उन्हें कैसे हल कर सकते हैं।
वस्तु-उन्मुख भाषाओं के साथ समस्या यह है कि उनके पास यह सब अंतर्निहित वातावरण है जो वे अपने साथ ले जाते हैं। आप एक केला चाहते थे लेकिन आपको जो मिला वह केला और पूरे जंगल को पकड़े हुए एक गोरिल्ला था । - जो आर्मस्ट्रांग, एरलांग के निर्माता
रोल-प्लेइंग गेम के पात्रों का पदानुक्रम बनाने की प्रक्रिया पर विचार करें। प्रारंभ में, दो प्रकार के पात्रों की आवश्यकता होती है - योद्धा और दाना, जिनमें से प्रत्येक का एक निश्चित मात्रा में स्वास्थ्य और एक नाम होता है। ये गुण सार्वजनिक हैं और इन्हें मूल वर्ण वर्ग में ले जाया जा सकता है।
class Character { constructor(name) { this.name = name; this.health = 100; } }
एक योद्धा अपनी सहनशक्ति खर्च करके हमला कर सकता है:
class Warrior extends Character { constructor(name) { super(name); this.stamina = 100; } fight() { console.log(`${this.name} takes a mighty swing!`); this.stamina--; } }
और एक दाना मंत्र दे सकता है जो मन की कुछ राशि खर्च करता है:
class Mage extends Character { constructor(name) { super(name); this.mana = 100; } cast() { console.log(`${this.name} casts a fireball!`); this.mana--; } }
अब, आइए एक नए वर्ग, पलाडिन का परिचय दें। एक पलाडिन मंत्र से लड़ सकता है और जादू कर सकता है। हम इसका समाधान कैसे कर सकते हैं? यहाँ कुछ समाधान दिए गए हैं जो लालित्य की समान कमी को साझा करते हैं:
fight()
और cast()
दोनों तरीकों को स्क्रैच से लागू कर सकते हैं। इस मामले में, DRY सिद्धांत का उल्लंघन किया जाता है क्योंकि प्रत्येक विधि निर्माण पर दोहराई जाएगी और परिवर्तनों को ट्रैक करने के लिए दाना और लड़ाकू वर्गों के तरीकों के साथ निरंतर सिंक्रनाइज़ेशन की आवश्यकता होगी।
fight()
और cast()
विधियों को चरित्र वर्ग स्तर पर लागू किया जा सकता है ताकि सभी तीन प्रकार के चरित्र उनके पास हों। यह थोड़ा बेहतर समाधान है, लेकिन इस मामले में, डेवलपर को दाना के लिए fight()
विधि और योद्धा के लिए कास्ट () विधि को ओवरराइड करना होगा, उन्हें खाली तरीकों से बदलना होगा या किसी त्रुटि को शांत करना होगा।रचना का उपयोग करके इन समस्याओं को एक कार्यात्मक दृष्टिकोण से हल किया जा सकता है। यह उनके प्रकारों से नहीं, बल्कि उनके कार्यों से शुरू करने के लिए पर्याप्त है। मूल रूप से, हमारे पास दो प्रमुख विशेषताएं हैं जो पात्रों की क्षमताओं को निर्धारित करती हैं - लड़ने की क्षमता और मंत्र डालने की क्षमता।
इन विशेषताओं को फ़ैक्टरी फ़ंक्शंस का उपयोग करके सेट किया जा सकता है जो चरित्र को परिभाषित करने वाले राज्य का विस्तार करते हैं:
const canCast = (state) => ({ cast: (spell) => { console.log(`${state.name} casts ${spell}!`); state.mana--; } }) const canFight = (state) => ({ fight: () => { console.log(`${state.name} slashes at the foe!`); state.stamina--; } })
इस प्रकार, एक चरित्र को इन क्षमताओं और प्रारंभिक गुणों के एक सेट द्वारा परिभाषित किया जाता है, दोनों सामान्य (नाम और स्वास्थ्य) और निजी (सहनशक्ति और मन):
const fighter = (name) => { let state = { name, health: 100, stamina: 100 } return Object.assign(state, canFight(state)); } const mage = (name) => { let state = { name, health: 100, mana: 100 } return Object.assign(state, canCast(state)); } const paladin = (name) => { let state = { name, health: 100, mana: 100, stamina: 100 } return Object.assign(state, canCast(state), canFight(state)); }
रचना के साथ, आप रचना का उपयोग करके वंशानुक्रम की समस्याओं से बच सकते हैं, और जावास्क्रिप्ट ऐसा करने के लिए एकदम सही भाषा है।