ฉันรู้ว่ามันถูกใช้มานานกว่า 1 ทศวรรษแล้วตั้งแต่มีการถามคำถามนี้ แต่ฉันแค่คิดถึงสิ่งนี้เป็นครั้งที่ n ในชีวิตนักเขียนโปรแกรมของฉันและพบวิธีแก้ปัญหาที่เป็นไปได้ที่ฉันไม่รู้ . ฉันไม่ได้เห็นวิธีการนี้เอกสารก่อนดังนั้นผมจะตั้งชื่อมันว่า "รัฐ / เอกชนรูปแบบดอลล่า" หรือ_ $ / $ รูปแบบ
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
ร้านค้าทุกสาขาในวัตถุตามความจำเป็น มันกำหนดฟังก์ชั่นในการเข้าถึงพวกเขาโดย นี่เป็นไปตามรูปแบบ get / set แบบสั้นดังนั้นหากผ่านไปแล้วจะถูกใช้เป็นค่าตัวแปรใหม่_$
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
_ $ / $ รูปแบบที่ช่วยให้ความเป็นส่วนตัวเต็มรูปแบบของค่าในการเรียนอย่างเต็มที่เป็นต้นแบบ ฉันไม่รู้ว่าฉันจะใช้สิ่งนี้หรือไม่ถ้ามีข้อบกพร่อง แต่เดี๋ยวก่อนมันเป็นปริศนาที่ดี!