ในช่วงเวลาที่มีสาขาวิทยาการคอมพิวเตอร์และการเขียนโปรแกรม โปรแกรมเมอร์เจ้าเล่ห์ได้ค้นพบความคล้ายคลึงกันที่เกิดขึ้นซ้ำในปัญหาที่พวกเขาพยายามจะแก้ไข การใช้ความคล้ายคลึงกันเหล่านี้ ทำให้มีการพัฒนารูปแบบการออกแบบที่หลากหลายซึ่งสามารถแก้ไขข้อจำกัดเฉพาะที่อาจมีได้ รูปแบบการออกแบบของผู้สังเกตการณ์ก็เป็นหนึ่งในกรณีดังกล่าว
รูปแบบการออกแบบของผู้สังเกตการณ์คืออะไร?
รูปแบบการออกแบบของผู้สังเกตการณ์ประกอบด้วยสององค์ประกอบหลัก: วัตถุและผู้สังเกตการณ์ โดยจะอธิบายความสัมพันธ์ระหว่างองค์ประกอบทั้งสองนี้ รวมถึงการดำเนินการที่องค์ประกอบทั้งสองสามารถทำได้ โดยทั่วไป ผู้เข้าร่วมจะรอจนกว่าเหตุการณ์จะเกิดขึ้นหรือถึงเกณฑ์ที่กำหนด จากนั้นพวกเขาจะแจ้งให้ผู้สังเกตการณ์ที่ต้องการทราบข้อมูลนั้นทราบ (Refactoring Guru) (Packt) ด้านล่างนี้คือการนำเสนอวัตถุและผู้สังเกตการณ์อย่างหยาบๆ สองภาพ ซึ่งผมจะนำไปใช้เป็นตัวอย่างในภายหลัง
เรื่อง
วัตถุมีสองงานหลัก: จัดการคำขอจากผู้สังเกตการณ์และแจ้งผู้สังเกตการณ์ที่เกี่ยวข้องเมื่อมีเหตุการณ์เกิดขึ้นหรือถึงเกณฑ์ที่กำหนด คำขอสองประเภทที่จัดการจากผู้สังเกตการณ์คือคำขอสมัครสมาชิกและยกเลิกการสมัคร เมื่อหัวเรื่องได้รับการร้องขอการสมัครจากผู้สังเกตการณ์ มันจะเพิ่มผู้สังเกตการณ์นั้นเข้าไปในรายชื่อผู้สังเกตการณ์ที่สมัครเป็นสมาชิก หากอาสาสมัครได้รับคำขอยกเลิกการสมัครจากผู้สังเกตการณ์ ก็จะลบผู้สังเกตการณ์นั้นออกจากรายการ (Refactoring Guru) เมื่อเหตุการณ์ของเรื่องเกิดขึ้นหรือถึงเกณฑ์ มันจะแจ้งให้ผู้สังเกตการณ์ที่สมัครเป็นสมาชิกทั้งหมดที่อยู่ในรายชื่อทราบ (Packt) ด้านล่างนี้ฉันได้เขียนโค้ด JavaScript สำหรับวิชาง่ายๆ โดยใช้แหล่งข้อมูลออนไลน์เพื่อเตือนตัวเองถึงไวยากรณ์ที่เหมาะสมสำหรับการกำหนดชั้นเรียนใน JavaScript (โรงเรียน W3) ในส่วนถัดไป ฉันมีข้อมูลโค้ดที่คล้ายกันสำหรับผู้สังเกตการณ์ ซึ่งอาจเป็นประโยชน์ในการทำความเข้าใจพฤติกรรมของโค้ดเรื่อง
class Subject { //The constructor sets up the object's data when initialized constructor(name) { this.name = name; this.observers = new Set(); } //notify() informs all interested observers of the subject //when the event has occured notify() { this.observers.forEach((observer) => { console.log(`${this.name} is notifying ${observer.name}`); setTimeout(() => { observer.handleNotify(this); }, 0); }) } //handleSubscribe() handles subscribe requests from observers handleSubscribe(observer) { this.observers.add(observer); } //handleSubscribe() handles unsubscribe requests from observers handleUnsubscribe(observer) { this.observers.delete(observer); } }
ผู้สังเกตการณ์
ผู้สังเกตการณ์ยังทำหน้าที่หลักสองประการ: การส่งคำขอไปยังอาสาสมัครและการจัดการการแจ้งเตือนจากอาสาสมัคร คำขอสองประเภทที่ผู้สังเกตการณ์ส่งไปยังอาสาสมัครคือคำขอสมัครสมาชิกและยกเลิกการสมัคร ซึ่งบอกให้ผู้สังเกตการณ์เพิ่มผู้สังเกตการณ์ลงในรายการที่สมัครเป็นสมาชิกหรือลบออกจากรายการตามลำดับ (Refactoring Guru) จากนั้น เมื่อผู้สังเกตการณ์ได้รับการแจ้งเตือนจากเรื่องใดเรื่องหนึ่ง ผู้สังเกตการณ์จะจัดการการแจ้งเตือนโดยดำเนินการให้เสร็จสิ้น (Packt) ด้านล่างนี้ฉันได้เขียนโค้ด JavaScript สำหรับผู้สังเกตการณ์ทั่วไป โดยใช้การอ้างอิงออนไลน์สำหรับไวยากรณ์ (โรงเรียน W3) อีกครั้ง ข้อมูลโค้ดนี้ทำงานร่วมกับข้อมูลโค้ดหัวเรื่องด้านบนเพื่อใช้รูปแบบการออกแบบของผู้สังเกตการณ์ที่สมบูรณ์
class Observer { //The constructor sets up the object's data when initialized constructor(name) { this.name = name; } //subscribe() lets a subject know that the observer is interested subscribe(subject) { subject.handleSubscribe(this); console.log(`I (${this.name}) have subscribed to ${subject.name}!`); } //unsubscribe() lets a subject know that the observer is no longer interested unsubscribe(subject) { subject.handleUnsubscribe(this); console.log(`I (${this.name}) have unsubscribed from ${subject.name}!`); } //handleNotify() handles what the Observer wants to do when notfied handleNotify(subject) { console.log(`I (${this.name}) have been notified by ${subject.name}!`); } }
วัตถุและผู้สังเกตการณ์โต้ตอบกัน
ตอนนี้เรารู้แล้วว่าทั้งตัวแบบและผู้สังเกตการณ์ทำงานอย่างไร การดูตัวอย่างปฏิสัมพันธ์ระหว่างวัตถุและผู้สังเกตการณ์จะมีประโยชน์มาก ด้านล่างนี้เป็นการ์ตูนที่สร้างจากภาพวาดหยาบๆ ของฉัน ซึ่งช่วยแสดงให้เห็นปฏิสัมพันธ์ระหว่างวัตถุและผู้สังเกตการณ์
สำหรับผู้ที่ชื่นชอบโค้ด การโต้ตอบแบบเดียวกันนี้จะอธิบายไว้ในข้อมูลโค้ดด้านล่างนี้ ฉันได้แสดงความคิดเห็นเกี่ยวกับผลกระทบของแต่ละบรรทัดที่อยู่ด้านล่าง
const eyeball = new Observer('eyeball'); const star = new Subject('star'); star.notify(); //Nothing Happens (star has no subscribed observers) eyeball.subscribe(star); //eyeball will be added to star's list of subscribed observers star.notify(); //star will notify eyeball, //since eyeball is on its list of subscribed observers eyeball.unsubscribe(star); //eyeball will be removed from star's list of subscribed observers star.notify(); //Nothing Happens (star has no subscribed observers)
เหตุใดรูปแบบการออกแบบนี้จึงเกี่ยวข้อง?
รูปแบบการออกแบบนี้มีความเกี่ยวข้องเนื่องจากปรากฏบ่อยมากในการพัฒนา UI แบบโต้ตอบและตอบสนอง (รวมถึงการออกแบบเว็บ) เนื่องจาก UI แบบโต้ตอบและแบบตอบสนองมักจะต้องมีการดำเนินการที่จะเกิดขึ้นหลังจากเกิดเหตุการณ์เฉพาะหรือถึงเกณฑ์ที่กำหนด ตัวอย่างเช่น หากนักพัฒนาเว็บต้องการให้หน้าเว็บดำเนินการเมื่อมีการคลิก ‹div› พวกเขาอาจเขียนโค้ดบางส่วนที่คล้ายกับตัวอย่างด้านล่าง ฟังก์ชัน addEventListener() สร้าง event Listener (ผู้สังเกตการณ์) ที่ดำเนินการเฉพาะเมื่อตัวจัดการเหตุการณ์ของ ‹div› (หัวเรื่อง) แจ้งว่ามีการคลิก (เหตุการณ์เฉพาะ) เกิดขึ้น (Dofactory) (Packt)
document.querySelector('#someDiv').addEventListener(click, () => {/* Do Something */})
อีกตัวอย่างหนึ่งของรูปแบบการออกแบบของผู้สังเกตการณ์ที่ใช้งานจริงคือ useState hook ใน React hook useState จะสร้างอ็อบเจ็กต์สถานะ (หัวเรื่อง) ซึ่งจะรอจนกระทั่งค่าของมันเปลี่ยนแปลง (เหตุการณ์เฉพาะ) เพื่อบอกตัวเรนเดอร์ React ว่าสถานะมีการเปลี่ยนแปลง จึงสามารถเรนเดอร์เพจอีกครั้งได้ (Fernández)
const [value, setValue] = useState('initial value');
ไม่ว่าคุณจะใช้รูปแบบการออกแบบของผู้สังเกตการณ์โดยตรงหรือใช้ไลบรารีที่นำไปใช้หรือไม่ รูปแบบการออกแบบจะปรากฏขึ้นบ่อยครั้ง หวังว่าบทความนี้จะช่วยให้ผู้อ่านมีความเข้าใจที่ดีขึ้นเกี่ยวกับวิธีการทำงานของรูปแบบการออกแบบภายใต้ประทุนและเมื่อใดที่อาจเป็นประโยชน์สำหรับพวกเขา
บรรณานุกรม
โรงงาน (n.d.) Jผู้สังเกตการณ์ avaScript โรงงาน ดึงข้อมูลเมื่อวันที่ 31 มีนาคม 2023 จาก https://www.dofactory.com/javascript/design-patterns/observer
Fernández, G. (2012, 1 ธันวาคม) ตอบสนอง hooks และรูปแบบ “ผู้สังเกตการณ์” ภาษาอังกฤษธรรมดา ดึงข้อมูลเมื่อวันที่ 31 มีนาคม 2023 จาก https://plainenglish.io/blog/react-hooks-and-the-observer-pattern-1e4274f0e5f5
แพ็ก (n.d.) รูปแบบผู้สังเกต แพ็ก ดึงข้อมูลเมื่อวันที่ 31 มีนาคม 2023 จาก https://subscription.packtpub.com/book/web-development/9781783287314/1/ch01lvl1sec12/the-observer-pattern
กูรูการปรับโครงสร้างใหม่ (n.d.) ผู้สังเกตการณ์ กูรูการปรับโครงสร้างใหม่ ดึงข้อมูลเมื่อวันที่ 31 มีนาคม 2023 จาก https://refactoring.guru/design-patterns/observer
โรงเรียน W3 (n.d.) คลาส JavaScript โรงเรียน W3 สืบค้นเมื่อวันที่ 31 มีนาคม 2023 จาก https://www.w3schools.com/js/js_classes.asp
รูปภาพที่ฉันสร้างขึ้นใน MS Paint
รหัสที่ฉันเขียนใน VS Code