ในช่วงเวลาที่มีสาขาวิทยาการคอมพิวเตอร์และการเขียนโปรแกรม โปรแกรมเมอร์เจ้าเล่ห์ได้ค้นพบความคล้ายคลึงกันที่เกิดขึ้นซ้ำในปัญหาที่พวกเขาพยายามจะแก้ไข การใช้ความคล้ายคลึงกันเหล่านี้ ทำให้มีการพัฒนารูปแบบการออกแบบที่หลากหลายซึ่งสามารถแก้ไขข้อจำกัดเฉพาะที่อาจมีได้ รูปแบบการออกแบบของผู้สังเกตการณ์ก็เป็นหนึ่งในกรณีดังกล่าว

รูปแบบการออกแบบของผู้สังเกตการณ์คืออะไร?

รูปแบบการออกแบบของผู้สังเกตการณ์ประกอบด้วยสององค์ประกอบหลัก: วัตถุและผู้สังเกตการณ์ โดยจะอธิบายความสัมพันธ์ระหว่างองค์ประกอบทั้งสองนี้ รวมถึงการดำเนินการที่องค์ประกอบทั้งสองสามารถทำได้ โดยทั่วไป ผู้เข้าร่วมจะรอจนกว่าเหตุการณ์จะเกิดขึ้นหรือถึงเกณฑ์ที่กำหนด จากนั้นพวกเขาจะแจ้งให้ผู้สังเกตการณ์ที่ต้องการทราบข้อมูลนั้นทราบ (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