1. โครงแผนของแพทเทิร์น Chain of Responsibility
แพทเทิร์น Chain of Responsibility เป็นแพทเทิร์นการออกแบบที่เกี่ยวกับพฤติกรรมที่ช่วยในการแยกความผูกพันระหว่างผู้ส่งและผู้รับของคำขอ ที่เป็นการที่อนุญาตให้วัตถุหลาย ๆ ตัวทำหน้าที่กับคำขอนี้ แต่ล่ะตัวรับมีการเก็บอ้างอิงไปที่ตัวรับถัดไป และถ้าไม่สามารถจัดการคำขอได้ จะส่งคำขอต่อไปยังตัวรับถัดไปจนกว่าคำขอจะได้รับการจัดการหรือมาถึงจุดสิ้นสุดของโซ่
2. ลักษณะและคุณสมบัติของแพทเทิร์น Chain of Responsibility
ลักษณะและคุณสมบัติของแพทเทิร์น Chain of Responsibility มีดังนี้:
- การแยกความผูกพันระหว่างผู้ส่งและผู้รับ: ผู้ส่งไม่จำเป็นต้องสนใจว่าผู้รับใดจัดการคำขอ หรือไม่จำเป็นต้องรู้จักตัวรับเจาะจงที่อยู่ในโซ่
- ความยืดหยุ่น: มีการอนุญาตให้เพิ่ม ลบ หรือเรียงลำดับตัวจัดการในโซ่ได้อย่างยืดหยุ่นโดยที่ไม่ต้องแก้ไขโค้ดของผู้ส่งและผู้รับ
- ความสามารถในการขยายออก: ง่ายต่อการขยายโซ่ความรับผิดชอบด้วยการเพิ่มตัวจัดการเจาะจงใหม่
- หลักความรับผิดชอบเดี่ยว: แต่ล่ะตัวจัดการเจาะจงจำเป็นที่จะต้องกลับความสนใจเฉพาะกับตัวเจาะจงของตน
- ความสามารถในการกำหนดค่า: โซ่ของตัวจัดการสามารถกำหนดค่าตามความต้องการให้คำขอต่าง ๆ มีโซ่ของตัวจัดการต่าง ๆ
3. ตัวอย่างการประยุกต์ใช้ของแพทเทิร์น Chain of Responsibility
แพทเทิร์น Chain of Responsibility มีการประยุกต์ใช้ทางปฏิบัติหลายอย่าง เช่น:
- การจัดการคำขอในแอปพลิเคชันเว็บ: สามารถนำมาใช้ในการจัดการกับประเภทคำขอต่าง ๆ เช่น การพิสูจน์ตัวตน, การบันทึกล็อก, และการตรวจสอบสิทธิ์
- การจัดการข้อผิดพลาด: สามารถนำมาใช้ในการจัดการกับข้อผิดพลาด โดยที่แต่ล่ะตัวจัดการรับผิดชอบการจัดการกับประเภทข้อผิดพลาดเจาะจง และส่งข้อผิดพลาดต่อไปถ้าจำเป็น
- การจัดการเหตุการณ์: สามารถนำมาใช้ในการจัดการกับประเภทต่าง ๆ ของเหตุการณ์ เช่น เหตุการณ์การคลิกของผู้ใช้, เหตุการณ์คำขอเครือข่าย และอื่น ๆ
4. การประยุกต์ใช้แพทเทิร์น Chain of Responsibility ใน Golang
4.1 แผนภาพคลาส UML
4.2 การแนะนำตัวอย่าง
ในแผนภาพคลาส UML ด้านบน เราได้กำหนดอินเตอร์เฟซของตัวจัดการ (Handler) และตัวจัดการในรูปแบบเจาะจง (ConcreteHandler1 และ ConcreteHandler2) ลูกค้า (Client) ดำเนินการส่งคำขอโดยการเรียกเมธอด handleRequest ของตัวจัดการ
4.3 ขั้นตอนการประยุกต์ใช้ 1: กำหนดอินเตอร์เฟซตัวจัดการเจาะจง
type Handler interface {
HandleRequest(request Request) error
SetNext(handler Handler)
}
type Request interface {
Condition bool
}
อินเตอร์เฟซตัวจัดการกำหนดเมธอด HandleRequest สำหรับการประมวลคำขอ และเมธอด SetNext สำหรับการกำหนดตัวจัดการถัดไป
4.4 ขั้นตอนการประยุกต์ใช้ 2: การสร้างคลาสตัวจัดการเจาะจง
type ConcreteHandler1 struct {
next Handler
}
func (h *ConcreteHandler1) HandleRequest(request Request) error {
// ตรรกะสำหรับการจัดการคำขอ
if request.Condition {
// โค้ดสำหรับการจัดการคำขอ
return nil
} else {
if h.next != nil {
return h.next.HandleRequest(request)
}
return errors.New("ไม่พบตัวจัดการ")
}
}
func (h *ConcreteHandler1) SetNext(handler Handler) {
h.next = handler
}
type ConcreteHandler2 struct {
next Handler
}
func (h *ConcreteHandler2) HandleRequest(request Request) error {
// ตรรกะสำหรับการจัดการคำขอ
if request.Condition {
// โค้ดสำหรับการจัดการคำขอ
return nil
} else {
if h.next != nil {
return h.next.HandleRequest(request)
}
return errors.New("ไม่พบตัวจัดการ")
}
}
func (h *ConcreteHandler2) SetNext(handler Handler) {
h.next = handler
}
คลาสตัวจัดการเจาะจงนี้นำอินเตอร์เฟซตัวจัดการมาใช้งานและโอเวอร์ไรด์เมธอด HandleRequest และ SetNext
4.5 ขั้นตอนการประยุกต์ใช้ 3: สร้างโซ่ของความรับผิดชอบ
handler1 := &ConcreteHandler1{}
handler2 := &ConcreteHandler2{}
handler1.SetNext(handler2)
โดยการสร้างตัวจัดการเจาะจงและกำหนดตัวจัดการถัดไป เราจึงสร้างโซ่ของความรับผิดชอบ
4.6 ขั้นตอนการประยุกต์ใช้ 4: รหัสลูกค้า
func main() {
handler := &ConcreteHandler1{}
// สร้างโซ่ของความรับผิดชอบ
handler.SetNext(&ConcreteHandler2{})
// ส่งคำขอ
handler.HandleRequest(Request{Condition: true})
}
ในรหัสลูกค้า เราสร้างตัวจัดการเจาะจง, กำหนดตัวจัดการถัดไป และเรียกเมธอด HandleRequest เพื่อส่งคำขอ