# Proxy Pattern

เจ้าตัวนี้ผมขอตั้งชื่อเป็นภาษาไทยว่า **ผู้ควบคุม** ละกัน ซึ่งมันอยู่ในกลุ่มของ [**🧱 Structural Patterns**](https://www.saladpuk.com/beginner-1/design-patterns/structural) โดยเจ้าตัวนี้จะมาช่วยแก้ปัญหาเมื่อ **เราต้องการจะควบคุมพฤติกรรม object ให้ได้ดั่งใจ** พูดแล้วก็ งงๆ ไปดูโจทย์ของเรากันเลยดีกว่าจะได้เข้าใจได้เร็วขึ้น

{% hint style="info" %}
**แนะนำให้อ่าน**\
บทความนี้เป็นส่วนหนึ่งของมหากาพย์ **Design Patterns** ที่จะมาเป็น guideline ในการแก้ปัญหาในการออกแบบซอฟต์แวร์โปรเจค หากใครสนใจอยากเข้าใจตั้งแต่ต้นว่ามันคืออะไร และเจ้า patterns ทั้ง 23 ตัวมีอะไรบ้าง ก็สามารถจิ้มตรงนี้เพื่อไปอ่านบทความหลักได้เบยครัช [👦 **Design Patterns**](https://saladpuk.gitbook.io/learn/beginner-1/design-patterns)
{% endhint %}

{% hint style="warning" %}
**หมายเหตุ**\
เนื้อหาของบทความนี้จะเน้นให้เข้าใจหลักการทำงานของ Design Patterns แต่ละตัว โดยภาพจากการ์ตูน One Piece มาใช้ประกอบ ซึ่งหลายๆอย่างนั้นมโนขึ้นมาเพื่อความสนุก และทำให้เข้าใจเนื้อหาได้ง่าย  *ลิขสิทธิ์ต่างๆอย่ามาจับผมนะผมโดนแมวน้ำครอบงำ + รู้เท่าไม่ถึงการ + ผมเป็นคนดี + ผมมีลูกมีเมียมีสามีที่ต้องดูแล* 😭
{% endhint %}

## 🧐 โจทย์

สมมุติว่ามี Web API ตัวหนึ่งชื่อ **พรหัก** ที่สอนธรรมะแบบแปลกๆแก่ชาวโลกอยู่ตัวหนึ่ง ซึ่งรัฐบาลโลกเห็นว่าเป็นภัยต่อความมั่นคง พลโท.การ์ป จึงสั่งการแบนมันทิ้งอย่างฉับพลัน

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-ML_tQJUTloAdC5t3LxN%2F-MLa6EVwq_vXBbgPkpC6%2Fimage.png?alt=media\&token=bfce8013-a7b1-42d9-a6dc-1a64ceb175d5)

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

1. ผู้ใช้ทุกคนต้อง **ใช้งาน API ได้เหมือนเดิมทุกอย่าง**
2. รัฐบาลโลกสามารถ **ควบคุม** เนื้อหาที่คิดว่าเป็นภัยต่อความมั่นคงได้
3. รัฐบาลโลก **กำหนดสิทธิในการเข้าถึง** เนื้อหาต่างๆได้
4. **เมื่อเราแก้ไขอะไรก็ตามผู้ใช้ต้องไม่รู้ตัวถึงการเปลี่ยนแปลงใดๆเลย**

เวลาที่ผู้ใช้จะเข้าเว็บอะไรก็ตาม มันจะต้องผ่าน **ผู้คุมกฎ** ก่อนเสมอ เพื่อให้ผู้คุมกฎไปเอาผลลัพท์กลับมาให้ดูนั่นเอง

🤔 ดังนั้นเราในฐาน Developer ที่ทำงานเป็นผู้คุมกฎ จะออกแบบยังไงถึงจะทำได้ครบทุกข้อตามที่รัฐบาลโลกสั่งมา ?

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLaBZrt3ThzqWdDKXuZ%2F-MLaFIza_yKdtYr0CH9m%2Fimage.png?alt=media\&token=8dbeffe8-c401-467a-9be6-a56d6d1d5ca1)

> หากไม่เห็นผมเขียนบทความใหม่ๆแล้ว ก็ฝากไปประกันตัวผมด้วย หรือว่างๆก็แวะมาทักทายกันได้นะ (ผมชอบกินเนื้อย่าง) 😭

## 🧒 แก้โจทย์ครั้งที่ 1

จากที่เล่ามาก็ดูเหมือนจะไม่มีไรยากชิมิ ในเมื่อทุกอย่างต้องผ่านเราอยู่แล้ว ดังนั้นเวลาที่ผู้ใช้ขอดูพระธรรมอะไรมา เราก็แค่ตรวจดูเนื้อหาในนั้นก่อนก็พอแล้วนิ

**เข้าใช้งานตามปรกติได้**\
ใครขออะไรมาก็ทำให้เขาไป แต่ขอตรวจเนื้อหาก่อนที่จะส่งไปให้ก่อนนะ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLabijXe05Gcjty-47N%2F-MLadhzi0jebAdaL3ARK%2Fimage.png?alt=media\&token=a17ca953-a553-4970-8e82-5d012d863d0a)

**ควบคุมเนื้อหาได้**\
ถ้าตรวจเนื้อหาแล้วมันอาจเป็นภัยต่อความมั่นคง เราก็**เปลี่ยนเนื้อหาเป็นอย่างอื่นที่เราอยากให้เป็น**ไปซะก็จบละ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLabijXe05Gcjty-47N%2F-MLafKTqJqLRPP4lAyy2%2Fimage.png?alt=media\&token=a93a3f50-edd5-4638-b667-e2775ac61b30)

**กำหนดสิทธิ์ในการเข้าถึง**\
ถ้าเนื้อหาไม่ได้เป็นภัยอะไร แต่เรารู้สึกว่าไม่เหมาะสมกับคนกลุ่มนี้ เราก็เปลี่ยนเป็นเนื้อหาที่เราคิดว่าเหมาะสมแทน

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLap_Spwt5FZwXpiMFB%2F-MLauiUrnQUTe4fm6iim%2Fimage.png?alt=media\&token=2bc95d63-bab4-4c03-9d1e-41ca2e193ae1)

ก็ดูเหมือนจะได้เกือบครบหมดแล้วนะ ดังนั้นเขียนโค้ดนิดหน่อยละกัน ครืดๆ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLajwSdRipCwrO7X9Tw%2F-MLalfo8VBeh9Nri4Bf9%2Fimage.png?alt=media\&token=32b77f9a-5d9a-41f8-b0a4-5141486cc359)

โดยจากรูปด้านบนจะเห็นว่า เมื่อไหร่ก็ตามที่ clients ขอดูเว็บ เราในฐานะผู้คุมกฎก็จะไปเรียกใช้ ApiRequestHandler ไปดึงข้อมูลต่อให้ ดังนั้นโค้ดที่ใช้ในการตรวจสอบเงื่อนไขสิ่งต่างๆก็จะอยู่ภายในคลาส ApiRequestHandler นั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLajwSdRipCwrO7X9Tw%2F-MLapE3MgXDvMnqjuQvH%2Fimage.png?alt=media\&token=58a4ee49-739d-42d6-868c-4e6b46b87244)

ดังนั้นโค้ดก็น่าจะออกมาราวๆนี้

```csharp
public class ApiRequestHandler
{
    private พรหัก api;
    public ApiRequestHandler(พรหัก api)
    {
        this.api = api;
    }
    
    public Content(string key)
    {
        var response = api.Content(key);
        // ตรวจสอบหรือแก้ไข response เพื่อให้เป็นแบบที่เราต้องการ
        return response;
    }
}
```

อะเชจากโค้ดด้านบนก็สามารถตอบโจทย์ทุกอย่างได้หมดละ แต่มันจะเกิดอะไรขึ้น **ถ้าเราอยากควบคุม api มากว่านี้ล่ะ?** ... หรือ **อยากเพิ่มเงื่อนไขเฉพาะเว็บนี้แต่เว็บอื่นไม่ต้องสนใจละ?** ... หรือ **ถ้า API ของพรหักเปลี่ยนล่ะ?** ... โค้ดใน ApiRequestHandler ก็จะต้องถูกแก้ไขอะดิ 😨

เพราะโค้ดของเรามันมีหลายอย่างที่ไม่ตรงหลักในการออกแบบที่ดี เช่น **SRP**, **OCP, DIP** ยังไงล่ะ

{% hint style="danger" %}
**Single-Responsibility Principle (SRP)**\
การออกแบบที่ละเมิดหลักในการออกแบบนี้จะทำให้ เวลาที่ Requirement เปลี่ยนมาทีนึง มันก็จมีโอกาสสูงมากที่การเปลี่ยนนั้นมันจะไปกระทบเจ้าสิ่งนั้น ทำให้เราต้องแก้ไขมัน ซึ่งผองเพื่อนอื่นๆที่มันดูแลอยู่นั้นไม่ได้เกี่ยวข้องเลยก็มีผลกระทบด้วยนั่นเอง ส่วนใครที่ลืมหรืออยากทบทวนเรื่อง SRP สามารถเข้าไปอ่านได้จากลิงค์นี้เบย [**Single-Responsibility Principle**](https://saladpuk.gitbook.io/learn/basic/solid/srp)
{% endhint %}

{% hint style="danger" %}
**Open & Close Principle (OCP)**\
การออกแบบที่ละเมิดหลักในการออกแบบนี้จะทำให้ทุกครั้งที่มีของใหม่ๆถูกเพิ่มเข้าไปปุ๊ป เราก็ต้องไปแก้โค้ดเดิมเสมอ สำหรับใครที่ลืมหลักในการออกแบบเรื่องนี้ไปแล้วให้กดอ่านได้จากตรงนี้ [**Open & Close Principle**](https://saladpuk.gitbook.io/learn/basic/solid/ocp)
{% endhint %}

{% hint style="danger" %}
**Dependency-Inversion Principle (DIP)**\
การละเมิดกฎข้อนี้จะทำให้ module หลักต้องถูกแก้ไขบ่อยๆ เมื่อตัวที่ทำงานตัวเล็กตัวน้อยมีการเปลี่ยนแปลง แม้จะเปลี่ยนเพียงแค่เล็กน้อยก็ตาม [**Dependency-Inversion Principle**](https://www.saladpuk.com/basic/solid/dip)
{% endhint %}

😢 เอาน่าไม่ต้องเสียใจไป เดี๋ยวเราลองวิเคราะห์ปัญหาแล้วลองแก้ไขมันไปทีละปมดูละกันนะ

## 🧒 แก้โจทย์ครั้งที่ 2

### 🔥 วิเคราะห์ปัญหา

โจทย์ในรอบนี้ความยากของมันคือ **จะควบคุมสิ่งที่ควบคุมไม่ได้ยังไง** ซึ่งเมื่อคุมได้ **เงื่อนไขต่างๆก็ต้องดูแลแยกจากตัวที่ถูกควบคุมอันอื่นด้วย**นั่นเอง ซึ่งเรื่องการควบคุมนี้ **ดช.แมวน้ำ** ได้เขียนอธิบายไว้ใน [**`Adapter Pattern`**](https://www.saladpuk.com/beginner-1/design-patterns/structural/adapter-pattern) แล้ว หากสนใจอยากดู Case Study ก็[**กดตรงนี้**](https://www.saladpuk.com/beginner-1/design-patterns/structural/adapter-pattern#undefined-2)เพื่อนไปดูต่อได้่เลยครับ

### 🔥 แก้ไขปัญหา

**เมื่อเรามีของที่เราควบคุมไม่ได้ เราต้องเปลี่ยนเป็นสิ่งที่เราควบคุมได้ก่อน** เพราะไม่อย่างนั้นสนุกแน่ ซึ่งการที่เราจะไปควบคุมของอื่นๆมีหลายวิธีเลย ซึ่งวิธีง่ายสุดคือการทำ **Wrapper Class** โดยเราจะสร้างคลาสขึ้นมาครอบของที่ควบคุมไม่ได้เอาไว้ แล้วเราก็ทำงานกับคลาสตัวนั้นแทนที่จะทำงานกับของที่ควบคุมไม่ได้นั่นเอง ตามรูปด้านล่าง

> Design Pattern ที่มีลักษณะเป็น Wrapper Class มีหลายตัวเลย เช่น [**Adapter**](https://www.saladpuk.com/beginner-1/design-patterns/structural/adapter-pattern), Decorator ลองไปศึกษาต่อได้

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLaxsHrepjtWEw5mQlS%2F-MLb-ntAEWEve5X58nAq%2Fimage.png?alt=media\&token=e70acfc0-458e-4d28-a8fb-b90d52d6d28d)

โดยปรกติ **Wrapper Class จะมีหน้าที่เพียงแค่เรื่องเดียวคือควบคุมสิ่งที่มันดูแลอยู่** ดังนั้นเราก็จะมี Wrapper Class เอาไว้ดูแล API พรหัก โดยเฉพาะเลย ตามรูปด้านล่าง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLb7dvimfigZDCohQuJ%2Fimage.png?alt=media\&token=fbd060c8-8e38-4162-aca1-23c4aecd0f7e)

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

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbCrR8bUuAxjNz0XuL%2Fimage.png?alt=media\&token=8b209398-7cd0-49a2-897c-e88a4c55fb07)

คราวนี้เวลาที่ **(1)** client ขอเข้าเว็บเมื่อไหร่ **(2.1)** เราก็จะเรียกใช้ตัว IWebApi มาทำงาน **(2.2)** ซึ่งตัว object จริงๆของมันคือ Wrapper **(3)** แต่ว่าเจ้า Wrapper มันไม่ได้ทำงานเอง มันจะคอยส่งไปให้ พรหัก API ต่างหาก (4) แล้วเมื่อได้ผลลัพท์กลับมา เจ้า Wrapper ก็จะคอยตรวจสอบ/แก้ไขผลลัพท์ให้เรียบร้อยก่อน (5) ค่อยส่งกลับไปให้ผู้ใช้ตามรูปนั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbJTUlVuP-ujbAuQXK%2Fimage.png?alt=media\&token=0074b2c7-2e90-47be-be0a-af3690e1029d)

🤠 หากเราอยากเพิ่ม/ลดเงื่อนไขต่างๆก็จะมีผลกระทบแค่กับคลาสเดียวนั่นคือ Wrapper นั่นเอง ซึ่งก็จะตรงกับกฎของ [**Single-Responsibility Principle**](https://saladpuk.gitbook.io/learn/basic/solid/srp) เรียบร้อย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbLqlEcxPAJ0v18_pj%2Fimage.png?alt=media\&token=275a140b-ffdc-4d2b-b1e3-7b2c9bd5893d)

🤠 จากที่ว่ามาก็จะทำให้เราสามารถ เพิ่มตัวที่อยากควบคุมอื่นๆเพิ่มเข้ามาได้เรื่อยๆ โดยไม่มีผลกระทบกับโค้ดเดิม ซึ่งตรงกับกฎของ [**Open & Close Principle**](https://saladpuk.gitbook.io/learn/basic/solid/ocp) เรียบร้อย และการแก้ไขเล็กๆน้อยๆก็จะไม่มีผลกระทบกับ Module หลัก ซึ่งตรงกับกฎ [**Dependency-Inversion Principle**](https://www.saladpuk.com/basic/solid/dip) เช่นกัลล์

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbL9QuSQNB43lp8V73%2Fimage.png?alt=media\&token=e142a834-62a6-478c-a2cb-eaf0aac0a9ed)

🤠 แถมการทำแบบนี้ก็จะทำให้ Wrapper ของเราเป็นหนึ่งเดียวกันกับสิ่งที่มันต้องการควบคุม ซึ่งก็จะตรงกับกฎ [**Liskov Substitution Principle**](https://www.saladpuk.com/basic/solid/lsp) อีกด้วย

{% hint style="danger" %}
**Liskov Substitution Principle (LSP)**\
การออกแบบที่ละเมิดหลักในการออกแบบนี้จะทำให้เราระแวงในการใช้ subclass เสมอ เพราะไม่แน่ใจว่า subclass ที่เอามาใช้ จะสามารถทำงานได้ 100% แบบคลาสแม่นั่นเอง สำหรับใครที่ลืมหลักในการออกแบบเรื่องนี้ไปแล้วให้กดอ่านได้จากตรงนี้ [**Liskov Substitution Principle (LSP)**](https://www.saladpuk.com/basic/solid/lsp)
{% endhint %}

😳 อุ๊ตะ!! พึ่งเห็นว่าลืมเปลี่ยนชื่อ Wrapper Class ซะได้ ดังนั้นเราก็เปลี่ยนมันเป็น Proxy เก๋ๆล้อกับสิ่งที่มันควบคุมอยู่ตามรูปด้านล่างนั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbO4lO0PB0_Lzet0XI%2Fimage.png?alt=media\&token=71ca8ca0-941e-494a-ba23-84b0d06270ad)

ยินดีด้วยในตอนนี้คุณได้ใช้สิ่งที่เรียกว่า **Proxy Pattern** เรียบร้อยแล้ว ไม่ว่าจะรู้ตัวหรือไม่ก็ตาม เย่ๆ 👏

## 🤔 Proxy Pattern คือไย ?

มันคือ **แนวคิดในการควบคุม object ให้ทำงานดั่งใจ** นั่นเอง โดยมีแนวคิดง่ายๆว่า ถ้าคุมมันไม่ได้ งั้นก็ส่งคนของเราไปคุมมันอีกทีละกัน แล้วเราจะสั่งให้คนของเราทำอะไรก็ได้ละทีนี้

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLbOTNLW317c0WW-p2a%2F-MLbRJsQgjLpgATRFsDv%2Fimage.png?alt=media\&token=1bd9b13c-5c44-4166-9c2e-543c4329bce0)

## 🤔 ประโยชน์จริงๆคือไย ?

ก็อย่างที่บอกว่าใช้ควบคุมของต่างๆที่เราคุมไม่ได้ แต่นอกเหนือจากนั้นจริงๆประโยชน์มันมีหลายอย่างเลย โดยเขาแบ่งมันออกเป็นกลุมต่างๆตามนี้

### 🔥 Virtual Proxy

หาก**ของที่เราจะเรียกใช้งานมันเปลืองทรัพยากร** เช่น ไฟล์รูปมันใหญ่มากเสียเวลาโหลด ดังนั้นเราก็สามารถใช้ Proxy ให้มันจำรูปที่เคยโหลดมาเก็บไว้เป็น memory cache แล้วถ้าเรียกใช้เมื่อไหร่ก็จะได้ไม่ต้องโหลดใหม่ก็ได้ (ของที่เป็นตระกูล caching data เราควรทำ expiration ให้มันด้วยเสมอ) หรือ การสร้าง object บางตัวค่อนค่างกินเวลา  แบบ Database Connection เราก็สามารถทำ cache เป็น connection pool ไว้ก่อนก็ได้

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLbUGT9G2-CmHAgnsRH%2F-MLbVAe2vfFKBNe03qP-%2Fimage.png?alt=media\&token=f2d7e900-1cb9-493d-bc75-3fde5cbe7f09)

### 🔥 Remote Proxy

หาก**ของที่เราจะเรียกใช้สามารถทำงานจากภายใน Local ได้** เช่น ของบางอย่างสามารถทำงานแบบง่ายๆได้จากตัว client เลยก็สามารถเขียนเป็น Proxy ให้มันทำงานในนั้นให้จบซะ ส่วนไหนทำไม่ได้ค่อยส่งมาที่ Server ก็ได้ เพราะของบางอย่าง client บางประเภทไม่สามารถเอา logic ไปเขียนไว้ในนั้นได้ เช่น ของที่มี sensitive logic ที่ไม่อยากให้คนอื่นเห็น

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLbUGT9G2-CmHAgnsRH%2F-MLbWpOhwT2pPc1BMOC_%2Fimage.png?alt=media\&token=9155aef0-b2ae-496f-a776-ef10047e443b)

### 🔥 Protective Proxy

หากของที่เราจะเรียกใช้จะต้องตรวจสอบสิทธิในการเข้าถึงก่อน เช่น เราตั้งเงื่อนไขว่าคนใช้งานต้องอายุเกิน 18 ปีขึ้นไป แต่ตัว API อีกฝั่งไม่ได้ตรวจเรื่องนี้ให้ เราก็สามารถตรวจเงื่อนไขก่อนที่จะเรียกใช้งานได้นั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLbWqxTFmEUvRItEqNU%2F-MLbYJbI_xTryJse15GK%2Fimage.png?alt=media\&token=343bc4f0-ca20-4f52-b25f-81a8044ec44a)

### 🔥 Smart Proxy

เจ้าตัวนี้จะคล้ายๆกับ **Remote Proxy** จนบางทีเขาก็มองว่ามันคืออันเดียวกัน ซึ่งหน้าที่ของมันคือดูว่าของที่จะตอบกลับไปจริงๆแล้วควรเป็นอะไรนั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLbWqxTFmEUvRItEqNU%2F-MLbZS-rRWZeUNYuw8GE%2Fimage.png?alt=media\&token=e248e208-4edf-43f3-9656-a76f4a5b20d2)

## 😎 Proxy Design

การออกแบบ Proxy นั้นสามารถทำได้หลายวิธีเลย และไม่จำเป็นต้องทำตามที่ **ดช.แมวน้ำ** บอกมานะ เพียงแค่คนส่วนใหญ่นิยมใช้แบบไหนป๋มก็เลยเอามาเขียนเจ๋ยๆ ซึ่งปรกติเราจะเห็นการออกแบบ Proxy 2 วิธีตามด้านล่าง

{% hint style="danger" %}
**ข้อควรระวัง**\
แบบที่ 1 และ แบบที่ 2 มันมีทั้งข้อดีข้อเสียคนละแบบกัน ดังนั้นก่อนเอาไปใช้ก็ชั่งน้ำหนักให้ดีก่อนนะกั๊ฟ แต่โดยปรกติตัวเลือกที่ 1 จะเหมาะสมและใช้งานได้ง่ายที่สุดนั่นเอง
{% endhint %}

#### แบบที่ 1 - สร้างมาตรฐานขึ้นมา แล้วใช้ร่วมกัน

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbCrR8bUuAxjNz0XuL%2Fimage.png?alt=media\&token=8b209398-7cd0-49a2-897c-e88a4c55fb07)

👍 **ข้อดี** - ของทุกอย่างถูกแยกขาดออกจากกัน ทำให้เราแก้ไขได้โดยไม่มีผลกระทบกับอีกตัว

👎 **ข้อเสีย** - เราก็ไม่สามารถเข้าถึงอีกฝั่งได้เยอะมากเท่าไหร่

#### แบบที่ 2 - Inherited จากตัวที่อยากควบคุมตรงๆ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MLb-qA5TMKq3he6usEj%2F-MLbAPuvse4hJGUQSd_3%2Fimage.png?alt=media\&token=a626b34b-2023-40ea-b2ad-afde5975dfa4)

👍 **ข้อดี** - เราสามารถใช้ความสามารถส่วนใหญ่ได้จากตัว base class เลย และ subclass ก็ได้อานิสงตามไปด้วย

👎 **ข้อเสีย** - ถ้าแก้ไขโค้ดที่ base class ก็จะส่งผลกระทบถึง sub class ด้วย

## 🎯 บทสรุป

### 👍 ข้อดี

การนำ **Proxy Pattern** มาใช้งานนั้นจะช่วย ลดการผูกกันของโค้ดลง แถมยังสามารถควบคุมการทำงานอีกฝั่งได้ดั่งใจแม้ว่าเราจะไม่ได้เป็นคนเขียนอีกฝั่งก็ตาม ซึ่งส่วนใหญ่เราจะใช้ควบคุม 3rd party library และสุดท้ายโค้ดของเราถูกแยกหน้าที่ออกให้ดูแลเป็นของใครของมัน (**Separation of Concerns**)

### 👎 ข้อเสีย

**เพิ่มความซับซ้อนโดยไม่จำเป็น** เพราะการนำ Proxy ไปใช้ จะทำให้เราไม่สามารถทำงานกับ Source ได้ตรงๆ

{% hint style="danger" %}
**ข้อควรระวัง**\
**อย่านำ Proxy Pattern ไปใช้มั่วซั่ว** เพราะมันทำให้โค้ดของเราซับซ้อนขึ้นเยอะเลยแทนที่เราจะเรียกใช้จาก Source ได้ตรงๆ เราจะต้องทำผ่าน Adapter อีกทีหนึ่ง ดังนั้นให้ชั่งน้ำหนักให้ดีเสียก่อนว่าปัญหาที่เราเจออยู่นั้น มันวุ่นวาย เทสยาก โค้ดมันผูกกันอยู่เยอะหรือเปล่า ถ้าชั่งน้ำหนักแล้ว + มีเหตุผลที่เพียงพอที่จะใช้ก็จงใช้ให้สบายใจไปเถิด
{% endhint %}

{% hint style="success" %}
เกลียด ชอบ ถูกใจ อยากติดตาม อยากติชมแนะนำด่าทอ หรืออะไรก็แล้วแต่ (ห้ามมายืมเงิน) จิ้มลงมาที่เพจนี้ได้เลย [**Mr.Saladpuk**](https://www.facebook.com/mr.saladpuk) และจะเป็นประคุณอันล้นพ้นถ้ากด Like + Follow + Share ให้ด้วยขอรับ น้ำตาจิไหล 🥺
{% endhint %}

![ช่องทางสนับสนุนค่าอาหารแมวน้ำกั๊ฟ 😘](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MKNgXXMPEbIB6sQztG2%2F-MKNmp9HEqzREDsXrZ0H%2Fpromptpay.png?alt=media\&token=0829926b-41a7-48d1-a515-4dea42ac4c2a)
