1. โครงแบบ Proxy คืออะไร

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

1.1 นิยามของโครงแบบ Proxy

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

1.2 วัตถุประสงค์และเป้าหมายของโครงแบบ Proxy

วัตถุประสงค์หลักของโครงแบบ proxy คือเพื่อให้มีวิธีการเข้าถึงออบเจ็กต์เป้าหมายอย่างอ้อมอก และสามารถเพิ่มฟังก์ชันเพิ่มเติมให้กับออบเจ็กต์เป้าหมายได้ ออบเจ็กต์พร็อกซีสามารถจัดการโลจิกที่เป็นร่วมกัน เช่น ควบคุมการเข้าถึงออบเจ็กต์เป้าหมาย การใช้แคช และการบันทึกข้อมูล โครงแบบ proxy ยังสามารถนำไปใช้ในการโหลดโลจิก (lazy loading) โดยสร้างออบเจ็กต์เป้าหมายขึ้นมาเมื่อมีความจำเป็นเท่านั้น

2. ลักษณะ และข้อดีของโครงแบบ Proxy

โครงแบบ proxy มีลักษณะ และข้อดี ดังนี้:

  • สามารถขยายฟังก์ชันของออบเจ็กต์เป้าหมายโดยไม่ต้องแก้ไขออบเจ็กต์เป้าหมาย
  • สามารถควบคุมการเข้าถึงออบเจ็กต์เป้าหมายผ่านออบเจ็กต์พร็อกซี
  • สามารถดำเนินการทำงานเพิ่มเติมก่อนหรือหลังการเข้าถึงออบเจ็กต์เป้าหมาย
  • สามารถนำไปใช้โหลดโลจิกโดยสร้างออบเจ็กต์เป้าหมายขึ้นมาเมื่อมีความจำเป็นเท่านั้น

3. ตัวอย่างการประยุกต์ใช้ของโครงแบบ Proxy

โครงแบบ proxy ถูกนำไปใช้อย่างแพร่หลายในฉากการใช้งานหลายแบบ ต่อไปนี้คือตัวอย่างการประยุกต์ใช้ที่พบบ่อย:

  • Remote Proxy: ใช้ในการเข้าถึงออบเจ็กต์บนเครือข่ายในท้องถิ่น
  • Virtual Proxy: ใช้ในการสร้างออบเจ็กต์ที่มีค่าสูงอย่างจำเป็น
  • Security Proxy: ใช้ในการควบคุมการเข้าถึงออบเจ็กต์
  • Smart Reference: ใช้ในการดำเนินการเพิ่มเติมเมื่อเข้าถึงออบเจ็กต์ เช่น การนับออบเจ็กต์

4.1 แผนภาพ UML สำหรับโครงแบบคลาส

ต่อไปนี้คือแผนภาพ UML สำหรับโครงแบบ Proxy ใน Golang:

Golang Proxy Pattern

4.2 บทนำตัวอย่าง

สมมติว่าเรามีอินเทอร์เฟส Subject ที่กำหนดเมธอด Request เรามีคลาสอินพลีเมนท์ชั่น RealSubject ซึ่งทำการอินพลีเมนท์อินเทอร์เฟส Subject จากนั้นเราสร้างคลาสพร็อกซี Proxy ซึ่งถือออบเจ็กต์ RealSubject และทำการอินพลีเมนท์อินเทอร์เฟส Subject ในเมธอด Request ของคลาส Proxy เราสามารถดำเนินการเพิ่มฟังก์ชันเพิ่มเติมก่อนหรือหลังการเรียกใช้เมธอด Request ของ RealSubject

4.3 ขั้นตอนการประมวลผลที่ 1: กำหนดอินเทอร์เฟสของพร็อกซี

ก่อนอื่นเราจำเป็นต้องกำหนดอินเทอร์เฟส Subject ซึ่งมีเมธอด Request:

package main

type Subject interface {
    Request()
}

4.4 ขั้นตอนการประมวลผลที่ 2: การอินพลีเมนท์ออบเจ็กต์เป้าหมาย

ต่อมาเราจะอินพลีเมนท์ออบเจ็กต์เป้าหมาย RealSubject ซึ่งทำการอินพลีเมนท์อินเทอร์เฟส Subject:

package main

import "fmt"

type RealSubject struct {}

func (r *RealSubject) Request() {
    fmt.Println("RealSubject: Handling Request")
}

4.5 ขั้นตอนการประมวลผลที่ 3: การอินพลีเมนท์ออบเจ็กต์พร็อกซี

ต่อมาเราจะสร้างออบเจ็กต์พร็อกซี Proxy ซึ่งถือออบเจ็กต์ RealSubject และทำการอินพลีเมนท์อินเทอร์เฟส Subject ในเมธอด Request ของคลาส Proxy เราสามารถดำเนินการเพิ่มฟังก์ชันเพิ่มเติมก่อนหรือหลังการเรียกใช้เมธอด Request ของ RealSubject

package main

import "fmt"

type Proxy struct {
    realSubject *RealSubject
}

func (p *Proxy) Request() {
    fmt.Println("Proxy: Pre-Request")
    
    if p.realSubject == nil {
        p.realSubject = &RealSubject{}
    }
    
    p.realSubject.Request()
    
    fmt.Println("Proxy: Post-Request")
}

4.6 ขั้นตอนการประมวลผลที่ 4: เรียกใช้ออบเจ็กต์พร็อกซี

สุดท้ายเราสามารถใช้ออบเจ็กต์พร็อกซี Proxy เพื่อเรียกใช้เมธอดของออบเจ็กต์ที่ถูกพร็อกซี RealSubject ได้

package main

func main() {
    proxy := Proxy{}
    proxy.Request()
}

การรันโค้ดข้างต้นจะได้ผลลัพธ์ดังนี้:

Proxy: Pre-Request
RealSubject: Handling Request
Proxy: Post-Request

5.1 ความแตกต่างและความเชื่อมโยงระหว่างรูปแบบบัญชีและรูปแบบตกแต่ง

ทั้งรูปแบบบัญชีและรูปแบบตกแต่งเป็นรูปแบบการออกแบบโครงสร้าง ทั้งสองรูปแบบมีวัตถุเป้าหมายและวัตถุเตรียม/ตกแต่ง อย่างไรก็ตาม มีความแตกต่างบางประการระหว่างทั้งสอง:

  • รูปแบบบัญชีมักเกี่ยวข้องกับการควบคุมการเข้าถึงวัตถุเป้าหมายในขณะที่รูปแบบตกแต่งเน้นการขยายวัตถุเป้าหมาย
  • รูปแบบบัญชีมักทำการดำเนินการเพิ่มเติมก่อนหรือหลังจากวัตถุเป้าหมายในขณะที่รูปแบบตกแต่งเพิ่มฟังก์ชันพิเศษได้โดยดีนามิกบนวัตถุเป้าหมาย

5.2 การเปรียบเทียบระหว่างรูปแบบบัญชีแบบคงที่และรูปแบบบัญชีแบบไดนามิก

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

5.3 การประยุกต์ใช้รูปแบบบัญชีในไมโครเซอร์วิส

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