मुझे पता है कि यह पूछे जाने के बाद 1 दशक से अधिक समय हो गया है, लेकिन मैंने अपने प्रोग्रामर के जीवन में n-th समय के लिए इस पर अपनी सोच रखी, और एक संभावित समाधान पाया जो मुझे नहीं पता कि क्या मैं पूरी तरह से अभी तक पसंद करता हूं । मैंने इस कार्यप्रणाली को पहले नहीं देखा है, इसलिए मैं इसे "निजी / सार्वजनिक डॉलर पैटर्न" या _ $ / $ पैटर्न का नाम दूंगा ।
var ownFunctionResult = this.$("functionName"[, arg1[, arg2 ...]]);
var ownFieldValue = this._$("fieldName"[, newValue]);
var objectFunctionResult = objectX.$("functionName"[, arg1[, arg2 ...]]);
//Throws an exception. objectX._$ is not defined
var objectFieldValue = objectX._$("fieldName"[, newValue]);
अवधारणा एक ClassDefinition फ़ंक्शन का उपयोग करती है जो एक इंटरफ़ेस फ़ंक्शन पर लौटने वाले एक कन्स्ट्रक्टर फ़ंक्शन को लौटाती है । इंटरफ़ेस की एकमात्र विधि है जो कंस्ट्रक्टर ऑब्जेक्ट में संबंधित फ़ंक्शन को लागू करने के लिए एक तर्क प्राप्त करती है , किसी भी अतिरिक्त तर्क को पारित होने के बाद पारित किया जाता है।$
name
name
विश्व स्तर पर परिभाषित सहायक फ़ंक्शन ClassValues
सभी फ़ील्ड को आवश्यकतानुसार एक ऑब्जेक्ट में संग्रहीत करता है। यह _$
उनके द्वारा उपयोग करने के लिए फ़ंक्शन को परिभाषित करता है name
। यह एक छोटे से गेट / सेट पैटर्न का अनुसरण करता है इसलिए यदि value
इसे पारित किया जाता है, तो इसे नए चर मान के रूप में उपयोग किया जाएगा।
var ClassValues = function (values) {
return {
_$: function _$(name, value) {
if (arguments.length > 1) {
values[name] = value;
}
return values[name];
}
};
};
वैश्विक रूप से परिभाषित फ़ंक्शन Interface
एक ऑब्जेक्ट और एक एकल फ़ंक्शन के साथ Values
लौटने के लिए एक ऑब्जेक्ट लेता है जो पैरामीटर के नाम पर एक फ़ंक्शन खोजने के लिए जांच करता है और इसे स्कॉप्ड ऑब्जेक्ट के रूप में आमंत्रित करता है । समारोह आह्वान पर पारित किए जाने वाले अतिरिक्त तर्क ।_interface
$
obj
name
values
$
var Interface = function (obj, values, className) {
var _interface = {
$: function $(name) {
if (typeof(obj[name]) === "function") {
return obj[name].apply(values, Array.prototype.splice.call(arguments, 1));
}
throw className + "." + name + " is not a function.";
}
};
//Give values access to the interface.
values.$ = _interface.$;
return _interface;
};
नीचे दिए गए नमूने में, ClassX
के परिणाम को सौंपा गया है ClassDefinition
, जो कि Constructor
फ़ंक्शन है। Constructor
किसी भी तर्क को प्राप्त कर सकते हैं। Interface
कंस्ट्रक्टर को कॉल करने के बाद बाहरी कोड क्या मिलता है।
var ClassX = (function ClassDefinition () {
var Constructor = function Constructor (valA) {
return Interface(this, ClassValues({ valA: valA }), "ClassX");
};
Constructor.prototype.getValA = function getValA() {
//private value access pattern to get current value.
return this._$("valA");
};
Constructor.prototype.setValA = function setValA(valA) {
//private value access pattern to set new value.
this._$("valA", valA);
};
Constructor.prototype.isValAValid = function isValAValid(validMessage, invalidMessage) {
//interface access pattern to call object function.
var valA = this.$("getValA");
//timesAccessed was not defined in constructor but can be added later...
var timesAccessed = this._$("timesAccessed");
if (timesAccessed) {
timesAccessed = timesAccessed + 1;
} else {
timesAccessed = 1;
}
this._$("timesAccessed", timesAccessed);
if (valA) {
return "valA is " + validMessage + ".";
}
return "valA is " + invalidMessage + ".";
};
return Constructor;
}());
इसमें गैर-प्रोटोटाइप फ़ंक्शन होने का कोई मतलब नहीं है Constructor
, हालांकि आप उन्हें कंस्ट्रक्टर फ़ंक्शन बॉडी में परिभाषित कर सकते हैं। सभी कार्यों को सार्वजनिक डॉलर पैटर्न के साथ कहा जाता है this.$("functionName"[, param1[, param2 ...]])
। निजी मूल्यों को निजी डॉलर पैटर्न के साथ एक्सेस किया जाता है this._$("valueName"[, replacingValue]);
। जैसा कि इसके Interface
लिए परिभाषा नहीं है _$
, मान बाहरी वस्तुओं द्वारा नहीं पहुँचा जा सकता है। चूंकि प्रत्येक प्रोटोटाइप फ़ंक्शन बॉडी फ़ंक्शन this
में values
ऑब्जेक्ट के लिए सेट है $
, इसलिए आपको सीधे कनस्ट्रक्टर सिबलिंग फ़ंक्शन को कॉल करने पर अपवाद मिलेगा; _ $ / $ पैटर्न की जरूरत नमूने समारोह शरीर में भी उसका अनुसरण किया। नीचे नमूना उपयोग।
var classX1 = new ClassX();
console.log("classX1." + classX1.$("isValAValid", "valid", "invalid"));
console.log("classX1.valA: " + classX1.$("getValA"));
classX1.$("setValA", "v1");
console.log("classX1." + classX1.$("isValAValid", "valid", "invalid"));
var classX2 = new ClassX("v2");
console.log("classX1.valA: " + classX1.$("getValA"));
console.log("classX2.valA: " + classX2.$("getValA"));
//This will throw an exception
//classX1._$("valA");
और कंसोल आउटपुट।
classX1.valA is invalid.
classX1.valA: undefined
classX1.valA is valid.
classX1.valA: v1
classX2.valA: v2
_ $ / $ पैटर्न पूरी तरह से नमूने के कक्षाओं में मूल्यों की पूर्ण गोपनीयता की अनुमति देता है। मुझे नहीं पता कि मैं कभी इसका इस्तेमाल करूंगा या नहीं, अगर इसमें कोई खामियां हैं, लेकिन हे, यह एक अच्छी पहेली थी!