Peter Seibel ผู้แต่ง Lisp Common Lisp เคยพูดว่าถ้าคุณต้องการรูปแบบบางอย่างจะต้องผิดพลาด ปัญหาที่เขากล่าวถึงหมายถึงความจำเป็นในการค้นหาและสรุปวิธีแก้ปัญหาทั่วไปเนื่องจากข้อบกพร่องของภาษาโดยธรรมชาติ
ไม่ว่าจะเป็นประเภทที่อ่อนแอหรือแข็งแกร่งภาษาคงที่หรือแบบไดนามิกภาษาที่จำเป็นหรือเชิงพรรณนาแต่ละภาษามีข้อดีและข้อเสียของตัวเอง นักกีฬาชาวจาเมกามีข้อได้เปรียบบางประการในการวิ่งและแม้แต่มวย แต่ขาดบางอย่างในการฝึกโยคะ
Warlocks และ Shadow Priests สามารถเป็นผู้ช่วยที่ยอดเยี่ยมได้อย่างง่ายดาย ในการเปลี่ยนไปใช้โปรแกรมอาจต้องใช้ความพยายามอย่างมากในการใช้งานตกแต่งในภาษาสแตติก เนื่องจาก JS สามารถโยนวิธีการบนวัตถุได้ตลอดเวลารูปแบบมัณฑนากรจึงไร้ประโยชน์ใน JS
มีหนังสือไม่กี่เล่มเกี่ยวกับรูปแบบการออกแบบ JavaScript "Pro JavaScript Design Patterns" เป็นหนังสือคลาสสิก แต่ตัวอย่างในนั้นค่อนข้าง verbose ดังนั้นตามรหัสที่ฉันเขียนในที่ทำงานฉันจะสรุปความเข้าใจของฉัน หากความเข้าใจของฉันมีอคติโปรดตรวจสอบให้แน่ใจ
1. โหมดซิงเกิลตัน
คำจำกัดความของรูปแบบ Singleton คือการสร้างอินสแตนซ์ที่ไม่ซ้ำกันของชั้นเรียน แต่ JS เองเป็นภาษา "ไร้คลาส" บทความจำนวนมากที่พูดถึงรูปแบบการออกแบบ JS ใช้ {} เป็นซิงเกิลตันและสมเหตุสมผล เนื่องจากมีหลายวิธีในการสร้างวัตถุโดย JS ลองมาดูซิงเกิลที่มีความหมายมากกว่านี้อีก
มีข้อกำหนดทั่วไปว่าเมื่อคลิกปุ่มเลเยอร์หน้ากากจะต้องปรากฏขึ้นบนหน้า ตัวอย่างเช่นเมื่อคุณคลิกที่ web.qq.com เพื่อเข้าสู่ระบบ
รหัสนี้ที่สร้างเลเยอร์มาสก์พื้นหลังสีเทานั้นง่ายต่อการเขียน
การคัดลอกรหัสมีดังนี้:
var createMask = function () {
ส่งคืนเอกสาร, body.appendchild (document.createelement (div));
-
$ ('ปุ่ม') .Click (function () {
var mask = createMask ();
Mask.show ();
-
ปัญหาคือเลเยอร์หน้ากากนี้มีความพิเศษทั่วโลกดังนั้นทุกครั้งที่คุณเรียก createMask จะมีการสร้าง div ใหม่แม้ว่ามันจะถูกลบออกในขณะที่ซ่อนเลเยอร์มาสก์ อย่างไรก็ตามเห็นได้ชัดว่าไม่มีเหตุผลที่จะทำสิ่งนี้
มาดูวิธีแก้ปัญหาที่สองสร้าง div นี้ที่จุดเริ่มต้นของหน้า จากนั้นอ้างถึงตัวแปร
การคัดลอกรหัสมีดังนี้:
var mask = document.body.appendchild (document.createelement ("div '));
$ ("ปุ่ม ') .Click (function () {
Mask.show ();
-
นี่ไม่ได้หมายความว่าจะมีการสร้าง Div เฉพาะหน้ากากเท่านั้นในหน้า แต่ปัญหาอื่นจะตามมา บางทีเราอาจไม่จำเป็นต้องใช้เลเยอร์หน้ากากนี้ซึ่งจะเสีย DIV และคุณควรจะตระหนี่มากเกี่ยวกับการทำงานของโหนด DOM
หากคุณสามารถใช้ตัวแปรให้พิจารณาว่ามีการสร้าง DIV หรือไม่?
การคัดลอกรหัสมีดังนี้:
หน้ากาก var;
var createMask = function () {
ถ้า (หน้ากาก) กลับมาหน้ากาก;
อื่น{
mask = document, body.appendchild (document.createelement (div));
หน้ากากกลับ;
-
-
มันดูดี แต่ที่นี่ฉันทำฟังก์ชั่นที่สร้างวัตถุคอลัมน์เดียว ลองมาดูกันว่ามีอะไรผิดปกติกับรหัสนี้
ก่อนอื่นฟังก์ชั่นนี้มีผลข้างเคียงบางอย่าง ฟังก์ชั่นจะเปลี่ยนการอ้างอิงไปยังหน้ากากตัวแปรภายนอกในร่างกายฟังก์ชั่น ในโครงการความร่วมมือหลายคน CreateMask เป็นฟังก์ชั่นที่ไม่ปลอดภัย ในทางกลับกันหน้ากากตัวแปรทั่วโลกไม่จำเป็น มาปรับปรุงกันเถอะ
การคัดลอกรหัสมีดังนี้:
var createMask = function () {
หน้ากาก var;
return function () {
กลับมาหน้ากาก || (mask = document.body.appendchild (document.createelement ('div')))))
-
-
การปิดอย่างง่ายใช้ในการห่อหน้ากากตัวแปรอย่างน้อยสำหรับฟังก์ชั่น createMask มันถูกปิด
บางทีเมื่อฉันเห็นสิ่งนี้ฉันคิดว่ารูปแบบซิงเกิลนั้นง่ายเกินไป แท้จริงแล้วรูปแบบการออกแบบบางอย่างนั้นง่ายมาก แม้ว่าฉันจะไม่เคยให้ความสนใจกับแนวคิดของรูปแบบการออกแบบ แต่ฉันก็ใช้รูปแบบการออกแบบบางอย่างในรหัสประจำวันของฉันโดยไม่รู้ตัว เช่นเดียวกับเมื่อฉันเข้าใจว่ารถเข็นของชายชราคืออะไรฉันคิดถึงมันเมื่อหลายปีก่อนมันกลับกลายเป็นว่านี่เป็นรถเข็นของชายชรา
รูปแบบการออกแบบ 23 รูปแบบใน GOF เป็นรูปแบบที่มีอยู่และใช้ซ้ำในการพัฒนาซอฟต์แวร์ หากโปรแกรมเมอร์ไม่ได้ตระหนักอย่างชัดเจนว่าเขาใช้รูปแบบบางอย่างเขาอาจพลาดการออกแบบที่เหมาะสมกว่าในครั้งต่อไป (ข้อความนี้มาจาก "โลกแห่งการเขียนโปรแกรมใน Matsumoto"
กลับไปที่หัวข้อซิงเกิลก่อนหน้านี้ยังคงมีข้อเสีย สามารถใช้เพื่อสร้างเลเยอร์หน้ากากเท่านั้น ถ้าฉันต้องการเขียนฟังก์ชั่นเพื่อสร้างวัตถุ XHR ที่ไม่ซ้ำกัน ฉันสามารถหาเสื้อคลุม Singleton ทั่วไปได้หรือไม่?
ฟังก์ชั่นใน JS เป็นประเภทแรกซึ่งหมายความว่าฟังก์ชั่นสามารถส่งผ่านเป็นพารามิเตอร์ มาดูรหัสสุดท้าย
การคัดลอกรหัสมีดังนี้:
var singleton = function (fn) {
ผลลัพธ์ var;
return function () {
ผลตอบแทน || (result = fn .apply (สิ่งนี้, อาร์กิวเมนต์));
-
-
var createMask = singleton (function () {
ส่งคืน document.body.appendchild (document.createelement ('div'));
-
ใช้ตัวแปรเพื่อบันทึกค่าคืนแรก หากได้รับการกำหนดตัวแปรจะถูกส่งคืนก่อนในการโทรครั้งต่อไป รหัสที่สร้างเลเยอร์หน้ากากจะถูกส่งผ่านไปยัง wrapper ซิงเกิลผ่านฟังก์ชั่นการโทรกลับ วิธีนี้เรียกว่าโหมดบริดจ์ เกี่ยวกับโหมดบริดจ์จะมีการใส่ในภายหลัง
อย่างไรก็ตามฟังก์ชั่นซิงเกิลไม่สมบูรณ์แบบมันต้องใช้ผลลัพธ์ตัวแปรเสมอเพื่อลงทะเบียนการอ้างอิงถึง DIV น่าเสียดายที่ลักษณะการทำงานของ JS นั้นไม่เพียงพอที่จะกำจัดการประกาศและข้อความอย่างสมบูรณ์