ใครสามารถให้คำตอบที่ยอมรับได้กับฉันเกี่ยวกับความแตกต่างระหว่างObserver
a Mediator
และ a และบทสรุปของเมื่อคุณควรใช้รูปแบบหนึ่งเหนืออีกรูปแบบหนึ่งได้หรือไม่
ฉันไม่แน่ใจว่าสถานการณ์แบบไหนที่จะต้องการObserver
และสิ่งที่จะต้องมีMediator
ใครสามารถให้คำตอบที่ยอมรับได้กับฉันเกี่ยวกับความแตกต่างระหว่างObserver
a Mediator
และ a และบทสรุปของเมื่อคุณควรใช้รูปแบบหนึ่งเหนืออีกรูปแบบหนึ่งได้หรือไม่
ฉันไม่แน่ใจว่าสถานการณ์แบบไหนที่จะต้องการObserver
และสิ่งที่จะต้องมีMediator
คำตอบ:
ในหนังสือต้นฉบับที่ใช้ชื่อว่า Observer and Mediator, รูปแบบการออกแบบ, องค์ประกอบของซอฟต์แวร์เชิงวัตถุที่ใช้ซ้ำได้กล่าวว่ารูปแบบ Mediator นั้นสามารถนำไปใช้งานได้โดยใช้รูปแบบของผู้สังเกตการณ์ อย่างไรก็ตามมันยังสามารถนำมาใช้โดยการมีเพื่อนร่วมงาน (ประมาณเทียบเท่ากับหัวเรื่องของรูปแบบผู้สังเกตการณ์) มีการอ้างอิงถึงคลาส Mediator หรืออินเทอร์เฟซผู้ไกล่เกลี่ย
มีหลายกรณีที่คุณต้องการใช้รูปแบบการสังเกตการณ์สิ่งสำคัญคือในวัตถุไม่ควรรู้ว่าวัตถุอื่นกำลังสังเกตเห็นสถานะของมันอย่างไร
ผู้ไกล่เกลี่ยมีความเฉพาะเจาะจงมากกว่านี้เล็กน้อยเพื่อหลีกเลี่ยงการมีชั้นเรียนสื่อสารโดยตรง แต่แทนที่จะเป็นคนกลาง สิ่งนี้ช่วยให้หลักการความรับผิดชอบเดี่ยว (Single Responsibility) ด้วยการอนุญาตให้การสื่อสารถูกถ่ายไปยังคลาสที่เพิ่งจัดการนั้น
ตัวอย่างผู้ไกล่เกลี่ยคลาสสิกอยู่ใน GUI ซึ่งวิธีการไร้เดียงสาอาจทำให้เกิดรหัสบนเหตุการณ์การคลิกปุ่มโดยบอกว่า "ถ้าแผง Foo ถูกปิดใช้งานและแผงบาร์มีป้ายกำกับว่า" โปรดป้อนวันที่ "จากนั้นอย่าโทรเซิร์ฟเวอร์ เป็นอย่างอื่นไปข้างหน้า "ซึ่งมีรูปแบบผู้ไกล่เกลี่ยมันสามารถพูดว่า" ฉันแค่ปุ่มและไม่มีธุรกิจทางโลกรู้เกี่ยวกับแผงฟูและป้ายชื่อบนแผงแผงดังนั้นฉันจะถามคนกลางของฉันถ้าโทรเซิร์ฟเวอร์ ตกลงตอนนี้ "
หรือหากมีการใช้งานโดยใช้รูปแบบของผู้สังเกตการณ์ปุ่มจะบอกว่า "เฮ้ผู้สังเกตการณ์ (ซึ่งรวมถึงคนกลาง) สถานะของฉันเปลี่ยนไป (มีคนคลิกฉัน) ทำอะไรกับมันถ้าคุณสนใจ" ในตัวอย่างของฉันที่อาจสมเหตุสมผลน้อยกว่า แต่บางครั้งก็ทำได้และความแตกต่างระหว่างผู้สังเกตการณ์และผู้ไกล่เกลี่ยน่าจะเป็นจุดประสงค์หนึ่งมากกว่าความแตกต่างของรหัส
รูปแบบการสังเกตการณ์ทำงานได้ดีเมื่อการประสานงานระหว่างผู้สังเกตการณ์ไม่เป็นสิ่งที่จำเป็นและสังเกตความสัมพันธ์ไปทางหนึ่ง
ตัวอย่างเช่นให้วัตถุ B และ C สังเกตวัตถุ A เมื่อวัตถุ A เกิดเหตุการณ์ X ขึ้นดังนั้นวัตถุ B ควรดำเนินการเมธอด Y () และวัตถุ C ควรดำเนินการเมธอด Z () หากวิธีการตาม () และ CZ () เป็นอิสระอย่างสมบูรณ์และไม่ต้องการการประสานงานให้ดำเนินการต่อและใช้รูปแบบการสังเกตการณ์
ในทางกลับกันหากต้องดำเนินการ BY () ก่อน CZ () คุณจะต้องการใช้รูปแบบผู้ไกล่เกลี่ยที่ผู้ไกล่เกลี่ยสรุปการประสานงานนี้ ในสถานการณ์นี้ผู้ไกล่เกลี่ย M จะสังเกตวัตถุ A และจะมีการอ้างอิงไปยังวัตถุ B และ C เมื่อเหตุการณ์ยิง X, M จะจัดการกับเหตุการณ์และเรียกใช้ BY () และ CZ () ตามลำดับที่กำหนด
นอกจากนี้หากวัตถุ A, B และ C จำเป็นต้องสังเกตซึ่งกันและกันดังนั้นการใช้สื่อกลางเนื่องจากตัวกลางจะไปไกลในการแยกวัตถุเหล่านี้ออกและหลีกเลี่ยงรหัสสปาเก็ตตี้
Observer
รูปแบบถูกนำมาใช้เมื่อมีการดำเนินการในระดับหนึ่ง (ชั้นสังเกต) ต้องการที่จะผลิตปฏิกิริยาในชั้นเรียนอื่น (ชั้นสังเกต) แต่มันเป็นเรื่องที่ไม่พึงประสงค์สำหรับการเรียนสังเกตที่จะคู่กับชั้นสังเกต นี่เป็นรูปแบบที่ธรรมดามาก ตัวแยกวิเคราะห์ SAX XML อาจเป็นตัวอย่างที่ดี ในการใช้ตัวแยกวิเคราะห์ SAX ไคลเอนต์ใช้ContentHandler
อินเทอร์เฟซเพื่อ "สังเกต" การดำเนินการแยกวิเคราะห์ ในฐานะที่เป็นตัวแยกวิเคราะห์พบองค์ประกอบของเอกสาร XML ContentHandler
จะเรียกวิธีการของ parser สามารถเรียกใช้โค้ดไคลเอ็นต์ได้ แต่ parser ไม่ได้เชื่อมโยงกับโค้ดไคลเอ็นต์
Mediator
รูปแบบคือการห่อหุ้มของรูปแบบของการใช้งานของชุดของวัตถุที่ รหัสลูกค้าเป็นคู่กับผู้ไกล่เกลี่ยแทนที่จะเป็นคู่กับคลาสอื่น ๆ มันคล้ายกับการรวมตัวยกเว้นอายุการใช้งานของวัตถุที่ห่อหุ้มนั้นไม่ขึ้นอยู่กับอายุการใช้งานของผู้ไกล่เกลี่ย
ในแง่ง่าย (ที่ฉันใช้เพื่อจดจำ):
ผู้สังเกตการณ์: ใช้เมื่อวัตถุหนึ่งต้องการได้รับแจ้งการเปลี่ยนแปลงสถานะในวัตถุอื่น (การพูดอย่างเคร่งครัดโดยใช้เหตุการณ์คือผู้สังเกตการณ์)
เพื่อที่จะเข้าใจผู้ไกล่เกลี่ยฉันพบว่าง่ายขึ้นเมื่อคุณพิจารณา Facade ก่อน: Facade รวมฟังก์ชันการทำงานของคลาสที่แยกจากกัน (บางครั้งระบบย่อยทั้งหมด) และให้ฟังก์ชันนั้นในอินเทอร์เฟซเดียว
ผู้ไกล่เกลี่ย: เหมือนกับ Facade ยกเว้นว่าจะรวมการทำงานของคลาสรวมทั้งหมดเพื่อสร้างฟังก์ชันการทำงานใหม่ (คำอธิบายที่ดีที่นี่ )