1. แพทเทิร์น Mediator คืออะไร
Mediator Pattern เป็นแพทเทิร์นในการออกแบบที่ลดการพึ่งพาตรงๆ ระหว่างอ็อบเจ็กต์โดยการโอนการสื่อสารไปยังอ็อบเจ็กต์ตัวกลาง ใน Mediator Pattern อ็อบเจ็กต์จะไม่สื่อสารโดยตรงกันและแทนนั้นจะสื่อสารผ่านอ็อบเจ็กต์ตัวกลาง
2. ลักษณะและข้อดีของ Mediator Pattern
ลักษณะและข้อดีของ Mediator Pattern มีดังนี้:
- ลดความผูกพันตรงระหว่างอ็อบเจ็กต์ ลดความซับซ้อนของระบบ
- ทำให้การสื่อสารระหว่างอ็อบเจ็กต์เป็นไปอย่างง่ายดายโดยมีอ็อบเจ็กต์ตัวกลางมาจัดการ
- ควบคุมการโต้ตอบระหว่างอ็อบเจ็กต์ได้ในที่เดียว ทำให้ง่ายต่อการขยายและการบำรุงรักษา
3. ตัวอย่างจริงๆของ Mediator Pattern
Mediator Pattern มีการใช้งานในสถานการณ์ชีวิตจริงหลายอย่าง เช่นในระบบกำหนดเวลารถบนท่าอากาศยาน การดิสพาตซิเป็นตัวกลางขณะที่โมดูลต่างๆ เช่นเครื่องบินและการจราจรภายใต้ดิน ทำหน้าที่เป็นคลาสเพื่อสื่อสารและประสานงานผ่านการดิสพาตเชียวกัน
4. การนำ Mediator Pattern มาใช้ใน Golang
4.1 การนำเสนอแผนผังคลาส UML
ด้านล่างนี้คือแผนผังคลาส UML สำหรับ Mediator Pattern ใน Golang:
4.2 การนำเสนอตัวอย่าง
ในตัวอย่างนี้ เราจะนำเสนอการปรับใช้แอปพลิเคชันห้องสนทนาง่ายๆ โดยใช้ Mediator Pattern เพื่อจัดการการสื่อสารระหว่างผู้ใช้งานท่านอื่นๆ
4.3 ขั้นตอนการปฏิบัติการทำอย่างที่ 1: กำหนดอินเตอร์เฟสและคลาสที่แนบมาที่ Mediator
ก่อนอื่น เราจะกำหนดคลาสอินเตอร์เฟสและคลาสคอนกรีท เพื่อปรับใช้ดังนี้:
type Mediator interface {
registerColleague(colleague Colleague)
sendMessage(message string, colleague Colleague)
}
type ConcreteMediator struct {
colleagues map[string]Colleague
}
func (m *ConcreteMediator) registerColleague(colleague Colleague) {
m.colleagues[colleague.getName()] = colleague
}
func (m *ConcreteMediator) sendMessage(message string, colleague Colleague) {
for _, c := range m.colleagues {
if c != colleague {
c.receiveMessage(message)
}
}
}
4.4 ขั้นตอนการปฏิบัติการทำอย่างที่ 2: กำหนดอินเตอร์เฟสและคลาสที่แนบมาที่ Colleague
ต่อมา เราจะกำหนดอินเตอร์เฟสและคลาสคอนกรีทต่างๆ ดังนี้:
type Colleague interface {
receiveMessage(message string)
sendMessage(message string)
getName() string
}
type ConcreteColleagueA struct {
mediator Mediator
name string
}
func (c *ConcreteColleagueA) receiveMessage(message string) {
fmt.Printf("%s received message: %s\n", c.name, message)
}
func (c *ConcreteColleagueA) sendMessage(message string) {
c.mediator.sendMessage(message, c)
}
func (c *ConcreteColleagueA) getName() string {
return c.name
}
type ConcreteColleagueB struct {
mediator Mediator
name string
}
func (c *ConcreteColleagueB) receiveMessage(message string) {
fmt.Printf("%s received message: %s\n", c.name, message)
}
func (c *ConcreteColleagueB) sendMessage(message string) {
c.mediator.sendMessage(message, c)
}
func (c *ConcreteColleagueB) getName() string {
return c.name
}
4.5 ขั้นตอนการปฏิบัติการทำอย่างที่ 3: การจัดการลูกค้าในตัวดิสพาต
ในคลาสตัวดิสพาตเฉพาะ เราจำเป็นต้องปฏิบัติการฟังก์ชัน registerColleague
และ sendMessage
เพื่อจัดการการสื่อสารระหว่างคลาสลูกค้า:
func main() {
mediator := &ConcreteMediator{
colleagues: make(map[string]Colleague),
}
colleagueA := &ConcreteColleagueA{
mediator: mediator,
name: "Colleague A",
}
colleagueB := &ConcreteColleagueB{
mediator: mediator,
name: "Colleague B",
}
mediator.registerColleague(colleagueA)
mediator.registerColleague(colleagueB)
colleagueA.sendMessage("Hello, World!")
colleagueB.sendMessage("Hi, there!")
}
ในฟังก์ชัน main
เราจะสร้างอ็อบเจ็กต์ตัวดิสพาตเฉพาะและอ็อบเจ็กต์ลูกค้าเฉพาะสองตัว จากนั้นลงทะเบียนอ็อบเจ็กต์ลูกค้าผ่านอ็อบเจ็กต์ตัวดิสพาตและทดสอบการสื่อสาร