यह वास्तव में बहुत आसान है:
कंस्ट्रक्टर होने के बजाय जो आपका सेटअप करता है,
// c-family pseudo-code
public class Thing {
public Thing (a, b, c, d) { this.x = a; this.y = b; /* ... */ }
}
... क्या आपका कंस्ट्रक्टर बहुत कम है या कुछ भी नहीं है, और एक विधि लिखी जाती है .init
या कहा जाता है .initialize
, जो कि आपका कंस्ट्रक्टर सामान्य रूप से करता है।
public class Thing {
public Thing () {}
public void initialize (a, b, c, d) {
this.x = a; /*...*/
}
}
तो अब बस के बजाय जा रहा है जैसे:
Thing thing = new Thing(1, 2, 3, 4);
तुम जा सकते हो:
Thing thing = new Thing();
thing.doSomething();
thing.bind_events(evt_1, evt_2);
thing.initialize(1, 2, 3, 4);
वहाँ लाभ यह है कि अब आप अपने सिस्टम में अधिक आसानी से निर्भरता-इंजेक्शन / उलटा नियंत्रण का उपयोग कर सकते हैं।
कहने के बजाय
public class Soldier {
private Weapon weapon;
public Soldier (name, x, y) {
this.weapon = new Weapon();
}
}
आप सैनिक का निर्माण कर सकते हैं, उसे एक सुसज्जित विधि दे सकते हैं, जहाँ आप उसे एक हथियार सौंप सकते हैं , और बाकी सभी निर्माण कार्यों को कॉल कर सकते हैं।
इसलिए अब, दुश्मनों को अधीन करने के बजाय, जहां एक सैनिक के पास एक पिस्तौल है और दूसरे के पास एक राइफल है और दूसरे के पास एक बन्दूक है, और यही एकमात्र अंतर है, आप बस कह सकते हैं:
Soldier soldier1 = new Soldier(),
soldier2 = new Soldier(),
soldier3 = new Soldier();
soldier1.equip(new Pistol());
soldier2.equip(new Rifle());
soldier3.equip(new Shotgun());
soldier1.initialize("Bob", 32, 48);
soldier2.initialize("Doug", 57, 200);
soldier3.initialize("Mike", 92, 30);
विनाश के साथ एक ही सौदा। यदि आपको विशेष आवश्यकताएं हैं (ईवेंट श्रोताओं को हटाकर, सरणियों से उदाहरणों को हटाना / जो भी संरचनाएं आपके साथ काम कर रही हैं, आदि), तो आप उन्हें मैन्युअल रूप से कॉल करेंगे, ताकि आपको पता चल जाए कि प्रोग्राम में कब और कहां हो रहा है।
संपादित करें
जैसा कि क्रियोटन ने नीचे बताया है, यह मूल पोस्ट के "हाउ" का उत्तर देता है , लेकिन वास्तव में एक "क्यों" का अच्छा काम नहीं करता है।
जैसा कि आप शायद ऊपर दिए गए उत्तर में देख सकते हैं, इसमें बहुत अंतर नहीं हो सकता है:
var myObj = new Object();
myObj.setPrecondition(1);
myObj.setOtherPrecondition(2);
myObj.init();
और लेखन
var myObj = new Object(1,2);
जबकि बस एक बड़ा निर्माता कार्य कर रहा है।
उन वस्तुओं के लिए एक तर्क दिया जाना चाहिए जिनकी 15 या 20 पूर्व-स्थितियां हैं, जो एक निर्माणकर्ता को काम करने के लिए बहुत कठिन बनाता है, और यह उन चीजों को देखने और याद रखने में आसान बनाता है, जो उन चीजों को इंटरफ़ेस में खींच कर निकालते हैं। , ताकि आप देख सकें कि तात्कालिकता कैसे काम करती है, एक स्तर अधिक।
वस्तुओं का वैकल्पिक-विन्यास इसका एक स्वाभाविक विस्तार है; ऑब्जेक्ट को चलाने से पहले इंटरफ़ेस पर वैकल्पिक रूप से मान सेट करना।
जेएस के पास इस विचार के लिए कुछ शानदार शॉर्टकट हैं, जो सिर्फ मजबूत-टाइप सी भाषाओं की तरह हैं।
उस ने कहा, संभावना है, अगर आप अपने निर्माणकर्ता में एक तर्क सूची के साथ काम कर रहे हैं, कि आपकी वस्तु बहुत बड़ी है और बहुत अधिक है, जैसा कि है। फिर से, यह एक व्यक्तिगत-प्राथमिकता वाली चीज है, और दूर-दूर तक अपवाद हैं, लेकिन यदि आप 20 चीजों को एक वस्तु में पास कर रहे हैं, तो संभावना अच्छी है कि आप उस वस्तु को कम करने का एक तरीका ढूंढ सकते हैं, छोटी वस्तुओं को बनाकर ।
एक अधिक प्रासंगिक कारण, और एक जो व्यापक रूप से लागू होता है वह यह होगा कि किसी वस्तु का आरंभीकरण अतुल्यकालिक डेटा पर निर्भर करता है, जो आपके पास वर्तमान में नहीं है।
आप जानते हैं कि आपको वस्तु की आवश्यकता है, इसलिए आप इसे वैसे भी बनाने जा रहे हैं, लेकिन इसे ठीक से काम करने के लिए, इसे सर्वर से या किसी अन्य फ़ाइल से डेटा की आवश्यकता होती है, जिसे अब लोड करना होगा।
फिर, चाहे आप आवश्यक डेटा को एक विशाल init में पास कर रहे हों, या एक इंटरफ़ेस का निर्माण कर रहे हों, अवधारणा के लिए वास्तव में महत्वपूर्ण नहीं है, जितना कि यह आपके ऑब्जेक्ट के इंटरफ़ेस और आपके सिस्टम के डिज़ाइन के लिए महत्वपूर्ण है ...
लेकिन वस्तु के निर्माण के संदर्भ में, आप ऐसा कुछ कर सकते हैं:
var obj_w_async_dependencies = new Object();
async_loader.load(obj_w_async_dependencies.async_data, obj_w_async_dependencies);
async_loader
एक फ़ाइलनाम, या एक संसाधन नाम या जो कुछ भी हो सकता है, उस संसाधन को लोड करें - शायद यह ध्वनि फ़ाइलों, या छवि डेटा को लोड करता है, या शायद यह सहेजे गए चरित्र आँकड़े लोड करता है ...
... और फिर यह उस डेटा को वापस फीड करेगा obj_w_async_dependencies.init(result);
।
इस तरह का डायनामिक वेब-एप्स में अक्सर पाया जाता है।
जरूरी नहीं कि किसी वस्तु के निर्माण में, उच्च-स्तरीय अनुप्रयोगों के लिए: उदाहरण के लिए, दीर्घाएँ तुरंत लोड हो सकती हैं और प्रारंभ हो सकती हैं, और फिर वे फ़ोटो को प्रदर्शित करते हैं जैसे कि वे स्ट्रीम करते हैं - यह वास्तव में एक async-initialization नहीं है, लेकिन जहां इसे अधिक बार देखा जाता है जावास्क्रिप्ट पुस्तकालयों में।
एक मॉड्यूल दूसरे पर निर्भर हो सकता है, और इसलिए जब तक आश्रितों का लोड पूरा नहीं हो जाता है, तब तक उस मॉड्यूल के आरंभीकरण को स्थगित किया जा सकता है।
इस के खेल-विशिष्ट उदाहरणों के संदर्भ में, एक वास्तविक Game
वर्ग पर विचार करें ।
हम निर्माता में .start
या कॉल क्यों नहीं कर सकते .run
?
संसाधनों को लोड करने की आवश्यकता है - बाकी सब कुछ बहुत अधिक परिभाषित किया गया है और जाने के लिए अच्छा है, लेकिन अगर हम बिना डेटाबेस-कनेक्शन के, या बनावट या मॉडल या आवाज़ या स्तरों के बिना गेम चलाने की कोशिश करते हैं, तो यह नहीं होगा एक विशेष रूप से दिलचस्प खेल ...
... तो क्या, फिर हम जो देखते हैं, उसके बीच का अंतर है Game
, सिवाय इसके कि हम इसकी "आगे बढ़ें" विधि को एक नाम दें, जो कि अधिक दिलचस्प है .init
(या इसके विपरीत, आरंभ को और भी अलग कर सकता है, अलग लोडिंग के लिए, जो चीजें लोड की गई हैं, उन्हें सेट करना और जब सब कुछ सेट हो चुका हो तो प्रोग्राम चलाना)।