ฉันต้องการถาม - ฉันเรียนรู้ช้า jQuery
สิ่งที่ฉันเห็นเป็นตัวอย่างที่แน่นอนของพระเจ้าวัตถุต่อต้านรูปแบบ โดยพื้นฐานแล้วทุกอย่างจะเข้าสู่$
ฟังก์ชั่นไม่ว่าจะเป็นอะไรก็ตาม
ฉันพูดถูกและเป็น jQuery จริง ๆ แล้วเป็นตัวอย่างของรูปแบบการต่อต้านนี้หรือไม่
ฉันต้องการถาม - ฉันเรียนรู้ช้า jQuery
สิ่งที่ฉันเห็นเป็นตัวอย่างที่แน่นอนของพระเจ้าวัตถุต่อต้านรูปแบบ โดยพื้นฐานแล้วทุกอย่างจะเข้าสู่$
ฟังก์ชั่นไม่ว่าจะเป็นอะไรก็ตาม
ฉันพูดถูกและเป็น jQuery จริง ๆ แล้วเป็นตัวอย่างของรูปแบบการต่อต้านนี้หรือไม่
คำตอบ:
เพื่อตอบคำถามนั้นฉันจะถามคำถามเชิงโวหารเกี่ยวกับโครงสร้างอื่นที่มีคุณสมบัติคล้ายกับองค์ประกอบ DOM ที่ jQuery ใช้งานนั่นคือตัววนรอบตัวเก่าที่ดี คำถามคือ:
คุณต้องใช้การทำงานกี่อย่างในตัววนซ้ำแบบง่าย?
คำถามสามารถตอบได้อย่างง่ายดายโดยดูที่ Iterator API ในภาษาที่กำหนด คุณต้องการ 3 วิธี:
นั่นคือทั้งหมดที่คุณต้องการ หากคุณสามารถดำเนินการ 3 อย่างเหล่านั้นคุณสามารถไปตามลำดับขององค์ประกอบใด ๆ
แต่นั่นไม่ใช่แค่สิ่งที่คุณมักต้องการทำกับลำดับขององค์ประกอบเท่านั้นใช่ไหม คุณมักจะมีเป้าหมายในระดับที่สูงขึ้นเพื่อให้บรรลุ คุณอาจต้องการทำบางสิ่งบางอย่างกับทุกองค์ประกอบคุณอาจต้องการกรองตามเงื่อนไขบางอย่างหรือหนึ่งในวิธีอื่น ๆ ดูอินเทอร์เฟซ IEnumerableในไลบรารี LINQ ใน. NET สำหรับตัวอย่างเพิ่มเติม
คุณเห็นว่ามีกี่คน? และนั่นเป็นเพียงส่วนย่อยของวิธีการทั้งหมดที่พวกเขาสามารถใส่ลงในอินเทอร์เฟซ IEnumerable เพราะคุณมักจะรวมพวกเขาเพื่อให้บรรลุเป้าหมายที่สูงขึ้น
แต่นี่คือการบิด วิธีการเหล่านั้นไม่ได้อยู่ในส่วนต่อประสาน IEnumerable พวกเขาเป็นวิธีการยูทิลิตี้อย่างง่ายที่จริง IEnumerable เป็นอินพุตและทำอะไรกับมัน ดังนั้นในภาษา C # ให้ความรู้สึกเหมือนมีวิธีการมากมายมหาศาลบนอินเทอร์เฟซ IEnumerable IEnumerable ไม่ใช่วัตถุเทพเจ้า
ตอนนี้กลับไปที่ jQuery ให้ถามคำถามนั้นอีกครั้งคราวนี้มีองค์ประกอบ DOM
คุณต้องการการดำเนินการจำนวนเท่าใดในองค์ประกอบ DOM
อีกครั้งคำตอบคือตรงไปตรงมาสวย วิธีการทั้งหมดที่คุณต้องการคือวิธีการอ่าน / แก้ไขคุณสมบัติและองค์ประกอบลูก เกี่ยวกับมัน. ทุกสิ่งอย่างอื่นเป็นเพียงการรวมกันของการดำเนินงานขั้นพื้นฐานเหล่านั้น
แต่คุณต้องการจะทำอะไรกับองค์ประกอบระดับสูงกว่านี้มากเท่าใด เช่นเดียวกับ Iterator: สิ่งที่แตกต่างกันมากถึงพันล้าน และนั่นคือสิ่งที่ jQuery เข้ามา jQuery ในสาระสำคัญมีสองสิ่ง:
หากคุณนำฟอร์ม sugared ออกมาคุณจะรู้ว่า jQuery สามารถเขียนได้ง่าย ๆ เป็นฟังก์ชั่นมากมายที่เลือก / แก้ไของค์ประกอบ DOM ตัวอย่างเช่น:
$("#body").html("<p>hello</p>");
... สามารถเขียนเป็น:
html($("#body"), "<p>hello</p>");
ความหมายมันเป็นสิ่งเดียวกัน อย่างไรก็ตามรูปแบบแรกมีข้อได้เปรียบที่ยิ่งใหญ่ซึ่งคำสั่งจากซ้ายไปขวาของคำสั่งจะเป็นไปตามลำดับที่การดำเนินการจะถูกดำเนินการ การเริ่มต้นครั้งที่สองที่อยู่ตรงกลางซึ่งทำให้การอ่านโค้ดยากมากถ้าคุณรวมการทำงานหลายอย่างเข้าด้วยกัน
ดังนั้นมันหมายความว่าอย่างไร jQuery นั้น (เช่น LINQ) ไม่ใช่รูปแบบต่อต้านพระเจ้า มันแทนกรณีของรูปแบบที่เคารพนับถือมากเรียกว่าเป็นมัณฑนากร
แต่แล้วอีกครั้งสิ่งที่เกี่ยวกับการแทนที่ของ$
การทำสิ่งต่าง ๆ เหล่านั้นทั้งหมดหรือไม่ นั่นคือน้ำตาลซินแทคติคจริงๆ การเรียกร้อง$
และสัญญาซื้อขายล่วงหน้า$.getJson()
ทั้งหมดเป็นสิ่งที่แตกต่างอย่างสิ้นเชิงที่เพิ่งเกิดขึ้นเพื่อแบ่งปันชื่อที่คล้ายกันเพื่อให้คุณสามารถรู้สึกได้ทันทีว่าพวกเขาเป็นของ jQuery $
ดำเนินการเพียงงานเดียวเท่านั้น: ให้คุณมีจุดเริ่มต้นที่จำได้ง่ายในการใช้ jQuery และวิธีการทั้งหมดที่คุณสามารถเรียกใช้บนวัตถุ jQuery ไม่ใช่อาการของวัตถุพระเจ้า พวกเขาเป็นฟังก์ชั่นยูทิลิตี้ที่แตกต่างกันเพียงอย่างเดียวที่แต่ละคนทำสิ่งหนึ่งและสิ่งเดียวในองค์ประกอบ DOM ส่งผ่านเป็นอาร์กิวเมนต์ สัญลักษณ์. dot อยู่ที่นี่เพียงเพราะทำให้การเขียนโค้ดง่ายขึ้น
ไม่ - $
ฟังก์ชั่นนี้ทำงานหนักเกินไปจริง ๆสำหรับสามงานเท่านั้น ทุกสิ่งทุกอย่างเป็นหน้าที่ของเด็กที่เพิ่งใช้เป็นnamespace
Math
แน่นอน เนื่องจากไม่มี namespace ในตัวใน JS พวกเขาเพียงใช้วัตถุสำหรับสิ่งนั้น แม้ว่าฉันไม่แน่ใจว่าทางเลือกอื่นจะเป็นอย่างไร ใส่ฟังก์ชั่นและคุณสมบัติทั้งหมดในเนมสเปซส่วนกลางหรือไม่
ฟังก์ชั่น jQuery หลัก (เช่น$("div a")
) เป็นหลักวิธีการโรงงานที่ส่งกลับตัวอย่างของประเภท jQuery ที่แสดงถึงคอลเลกชันขององค์ประกอบ DOM
อินสแตนซ์ของชนิด jQuery เหล่านี้มีวิธีการจัดการ DOM จำนวนมากซึ่งมีให้ใช้งานบนองค์ประกอบ DOM ที่แสดงโดยอินสแตนซ์ แม้ว่าสิ่งนี้จะถือว่าเป็นคลาสที่โตใหญ่เกินไป แต่ก็ไม่สอดคล้องกับรูปแบบของ Object Object
ในที่สุดตามที่ Michael Borgwardt กล่าวถึงก็มีฟังก์ชั่นยูทิลิตี้จำนวนมากที่ใช้ $ เป็น namespace และมีความเกี่ยวข้องกับวัตถุ jQuery ของคอลเลกชัน DOM เท่านั้น
$
ไม่ใช่วัตถุมันเป็นเนมสเปซ
คุณจะเรียก java.lang อ็อบเจกต์เทพเจ้าเพราะมีหลายคลาสในนั้นหรือไม่? มันเป็นไวยากรณ์ที่ถูกต้องอย่างแน่นอนในการโทรjava.lang.String.format(...)
คล้ายกันมากในรูปแบบการโทรอะไรบน jQuery
วัตถุเพื่อที่จะเป็นวัตถุพระเจ้าจะต้องเป็นวัตถุที่เหมาะสมในสถานที่แรก - มีทั้งข้อมูลและความฉลาดในการดำเนินการกับข้อมูล jQuery มีวิธีการเท่านั้น
อีกวิธีหนึ่งในการมองดู: การวัดที่ดีสำหรับวัตถุเทพเจ้ามากว่าวัตถุคือการติดต่อกัน - การทำงานร่วมกันที่ต่ำกว่าหมายถึงวัตถุของพระเจ้ามากขึ้น การทำงานร่วมกันบอกว่าเป็นส่วนหนึ่งของข้อมูลที่ถูกใช้โดยวิธีการหลายวิธี เนื่องจากไม่มีข้อมูลใน jQuery คุณทำคณิตศาสตร์ - ทุกวิธีใช้ข้อมูลทั้งหมดดังนั้น jQuery จึงมีความเหนียวแน่นสูงดังนั้นจึงไม่ใช่วัตถุพระเจ้า
เบนจามินขอให้ฉันชี้แจงตำแหน่งของฉันดังนั้นฉันจึงแก้ไขโพสต์ก่อนหน้าของฉันและเพิ่มความคิดเพิ่มเติม
บ็อบมาร์ตินเป็นผู้แต่งหนังสือยอดเยี่ยมเรื่อง Clean Code ในหนังสือเล่มนั้นมีบท (บทที่ 6) ที่เรียกว่าวัตถุและโครงสร้างข้อมูลซึ่งเขากล่าวถึงความแตกต่างที่สำคัญที่สุดระหว่างวัตถุและโครงสร้างข้อมูลและอ้างว่าเราต้องเลือกระหว่างพวกเขาเพราะการผสมพวกเขาเป็นความคิดที่ไม่ดีมาก
ความสับสนนี้บางครั้งนำไปสู่โครงสร้างไฮบริดที่โชคร้ายที่เป็นวัตถุครึ่งหนึ่งและโครงสร้างข้อมูลครึ่งหนึ่ง พวกเขามีฟังก์ชั่นที่ทำสิ่งที่สำคัญและพวกเขายังมีตัวแปรสาธารณะหรือสาธารณะ accessors และ mutators ที่สำหรับทุก intents และวัตถุประสงค์ทำให้ตัวแปรส่วนตัวสาธารณะสาธารณะดึงดูดฟังก์ชั่นภายนอกอื่น ๆ ที่จะใช้ตัวแปรเหล่านั้นวิธีที่โปรแกรมขั้นตอนจะใช้ โครงสร้างข้อมูล 4 ลูกผสมดังกล่าวทำให้ยากที่จะเพิ่มฟังก์ชั่นใหม่ แต่ก็ทำให้ยากที่จะเพิ่มโครงสร้างข้อมูลใหม่ พวกเขาเลวร้ายที่สุดของทั้งสองโลก หลีกเลี่ยงการสร้างพวกเขา พวกเขาบ่งบอกถึงการออกแบบที่ยุ่งเหยิงซึ่งผู้เขียนไม่แน่ใจ - หรือแย่กว่าไม่รู้ว่าพวกเขาต้องการการปกป้องจากฟังก์ชั่นหรือประเภท
ฉันคิดว่า DOM เป็นตัวอย่างของวัตถุและโครงสร้างข้อมูลลูกผสมเหล่านี้ เช่น DOM เราเขียนโค้ดดังนี้:
el.appendChild(node);
el.childNodes;
// bleeding internals
el.setAttribute(attr, val);
el.attributes;
// bleeding internals
el.style.color;
// at least this is okay
el = document.createElement(tag);
doc = document.implementation.createHTMLDocument();
// document is both a factory and a tree root
DOM ควรเป็นโครงสร้างข้อมูลอย่างชัดเจนแทนที่จะเป็นไฮบริด
el.childNodes.add(node);
// or el.childNodes[el.childNodes.length] = node;
el.childNodes;
el.attributes.put(attr, val);
// or el.attributes[attr] = val;
el.attributes;
el.style.get("color");
// or el.style.color;
factory = new HtmlNodeFactory();
el = factory.createElement(document, tag);
doc = factory.createDocument();
เฟรมเวิร์ก jQuery เป็นพวงของโพรซีเดอร์ซึ่งสามารถเลือกและแก้ไขคอลเล็กชันของโหนด DOM และทำสิ่งอื่น ๆ อีกมากมาย ลอเรนต์ชี้ให้เห็นในโพสต์ของเขา jQuery เป็นอะไรเช่นนี้ภายใต้ประทุน:
html(select("#body"), "<p>hello</p>");
ผู้พัฒนา jQuery ได้รวมขั้นตอนเหล่านี้ทั้งหมดไว้ในชั้นเรียนเดียวซึ่งมีหน้าที่รับผิดชอบต่อคุณสมบัติทั้งหมดที่ระบุไว้ข้างต้น ดังนั้นจึงเป็นการละเมิดหลักการความรับผิดชอบเดี่ยวอย่างชัดเจนและดังนั้นจึงเป็นวัตถุเทพเจ้า สิ่งเดียวเพราะมันไม่ทำลายอะไรเพราะมันเป็นคลาสแบบสแตนด์อโลนเดียวซึ่งทำงานในโครงสร้างข้อมูลเดียว (คอลเลกชันของโหนด DOM) ถ้าเราจะเพิ่มคลาสย่อย jQuery หรือโครงสร้างข้อมูลอื่นโครงการจะยุบอย่างรวดเร็ว ดังนั้นฉันไม่คิดว่าเราสามารถพูดคุยเกี่ยวกับ oo โดย jQuery มันค่อนข้างเป็นขั้นตอนกว่า oo แม้ว่าจะมีการกำหนดชั้นเรียน
สิ่งที่ Laurent อ้างว่าเป็นเรื่องไร้สาระสมบูรณ์:
ดังนั้นมันหมายความว่าอย่างไร jQuery นั้น (เช่น LINQ) ไม่ใช่รูปแบบต่อต้านพระเจ้า มันเป็นกรณีของรูปแบบที่น่านับถืออย่างมากที่เรียกว่ามัณฑนากร
รูปแบบของ Decorator นั้นเกี่ยวกับการเพิ่มฟังก์ชั่นใหม่โดยการรักษาอินเทอร์เฟซและไม่ปรับเปลี่ยนคลาสที่มีอยู่ ตัวอย่างเช่น:
คุณสามารถกำหนด 2 คลาสซึ่งใช้อินเทอร์เฟซเดียวกัน แต่ใช้งานแตกต่างกันโดยสิ้นเชิง:
/**
* @interface
*/
var Something = function (){};
/**
* @argument {string} arg1 The first argument.
* @argument {string} arg2 The second argument.
*/
Something.prototype.doSomething = function (arg1, arg2){};
/**
* @class
* @implements {Something}
*/
var A = function (){
// ...
};
/**
* @argument {string} arg1 The first argument.
* @argument {string} arg2 The second argument.
*/
A.prototype.doSomething = function (arg1, arg2){
// doSomething implementation of A
};
/**
* @class
* @implements {Something}
*/
var B = function (){
// ...
};
/**
* @argument {string} arg1 The first argument.
* @argument {string} arg2 The second argument.
*/
B.prototype.doSomething = function (arg1, arg2){
// doSomething implementation of B
// it is completely different from the implementation of A
// that's why it cannot be a sub-class of A
};
หากคุณมีวิธีการที่ใช้อินเทอร์เฟซทั่วไปเท่านั้นคุณสามารถกำหนด Decorator หนึ่งรายการขึ้นไปแทนที่จะคัดลอกโค้ดที่เหมือนกันระหว่าง A และ B คุณสามารถใช้มัณฑนากรเหล่านี้แม้ในโครงสร้างที่ซ้อนกัน
/**
* @class
* @implements {Something}
* @argument {Something} something The decorated object.
*/
var SomethingDecorator = function (something){
this.something = something;
// ...
};
/**
* @argument {string} arg1 The first argument.
* @argument {string} arg2 The second argument.
*/
SomethingDecorator.prototype.doSomething = function (arg1, arg2){
return this.something.doSomething(arg1, arg2);
};
/**
* A new method which can be common by A and B.
*
* @argument {function} done The callback.
* @argument {string} arg1 The first argument.
* @argument {string} arg2 The second argument.
*/
SomethingDecorator.prototype.doSomethingDelayed = function (done, arg1, arg2){
var err, res;
setTimeout(function (){
try {
res = this.doSomething(o.arg1, o.arg2);
} catch (e) {
err = e;
}
callback(err, res);
}, 1000);
};
ดังนั้นคุณสามารถแทนที่อินสแตนซ์ดั้งเดิมด้วยอินสแตนซ์ของมัณฑนากรในโค้ดระดับนามธรรมที่สูงขึ้น
function decorateWithManyFeatures(something){
var d1 = new SomethingDecorator(something);
var d2 = new AnotherSomethingDecorator(d1);
// ...
return dn;
}
var a = new A();
var b = new B();
var decoratedA = decorateWithManyFeatures(a);
var decoratedB = decorateWithManyFeatures(b);
decoratedA.doSomethingDelayed(...);
decoratedB.doSomethingDelayed(...);
ข้อสรุปว่า jQuery ไม่ใช่ Decorator ของสิ่งใดเพราะมันไม่ได้ใช้อินเทอร์เฟซเดียวกันกับ Array, NodeList หรือวัตถุ DOM อื่นใด มันใช้อินเทอร์เฟซของตัวเอง ไม่ได้ใช้โมดูลเป็นตัวตกแต่งเช่นกันพวกมันก็แค่แทนที่ต้นแบบดั้งเดิม ดังนั้นรูปแบบมัณฑนากรจึงไม่ได้ใช้ใน jQuery lib ทั้งหมด คลาส jQuery เป็นเพียงอะแดปเตอร์ขนาดใหญ่ซึ่งให้เราใช้ API เดียวกันโดยเบราว์เซอร์ที่แตกต่างกันมากมาย จากมุมมองของ oo มันเป็นระเบียบที่สมบูรณ์ แต่นั่นไม่สำคัญเลยมันทำงานได้ดีและเราใช้มัน
$
ฟังก์ชันหรือjQuery
วัตถุ