# Creational Patterns

![](/files/-Lpw38dzLSi3xwLGeA8M)

{% hint style="success" %}
**Best Practice**\
Program to an interface and not to an implementation. หรือเราสามารถแปลง่ายๆได้ว่า การเขียนโค้ดต่างๆ **ไม่ควรไปทำงานกับของระดับล่าง** **แต่จงทำงานกับระดับ abstraction เท่านั้น**
{% endhint %}

## 🤔 ทำไมต้องเป็นแบบนั้น ?

ขออธิบายให้เห็นภาพก่อนว่า ในชีวิตจริงถ้าเราจะสร้างบ้านซักหลัง เราจะเดินไปบอก **กรรมกร** หรือ **ผู้รับเหมา** เพื่อให้เขาสร้างบ้านให้เรากัน? ... คำตอบก็คือผู้รับเหมายังไงล่ะ เพราะเขามีหน้าที่รับผิดชอบสร้างบ้านให้เรา ซึ่งเขาก็จะไปสั่งงานกรรมกรมาสร้างบ้านให้เราอีกทีหนึ่ง ซึ่งถ้ากรรมกพวกนั้นเกเร ผู้รับเหมาก็อาจจะเปลี่ยนกรรมกรก็ได้ ซึ่งก็ไม่เกี่ยวข้องอะไรกับเรานั่นเอง (Builder Patterns)

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

```csharp
Dog dog = new Dog();
```

ซึ่งเจ้าโค้ดด้านบนก็ไม่ได้ผิดอะไรนะ **แต่มันผิดหลักในการออกแบบ** 😲 เพราะโค้ดของเราตอนนี้กำลังทำงานกับของระดับล่างอยู่ เพราะเราใช้คำสั่ง **new** ยังไงล่ะ และคลาส Dog มันก็เป็นการทำงานระดับล่าง หรือที่เราเรียกว่าระดับ Implementation แล้วยังไงล่ะ

### 👎 ข้อเสียในการทำงานกับของระดับล่าง

![](/files/-LoQZRJ54G6mQeUbUWpF)

จากโค้ดด้านบน มันจะเป็นการ**ผูกการทำงาน**ของเราให้ต้องทำงานกับคลาส Dog เท่านั้น **ไม่สามารถทำงานกับคลาสอื่นได้** ซึ่งถ้าเราอยากเปลี่ยนให้มันทำงานกับคลาสอื่นๆ เช่น คลาสแมว คลาสหมู ไรงี้ เราจะต้องเขียนโค้ดและ Compile มันใหม่ยกชุดเท่านั้น ซึ่งเราเรียกโค้ดลักษณะนี้ว่า **Hardcode** นั่นเอง

{% hint style="info" %}
**ข้อแนะนำ**\
การเขียนโค้ดโดยใช้คำสั่ง new ก็ไม่ได้ผิดอะไรร้ายแรงหรอก เพียงแค่โค้ดมันไม่ยืดหยุ่นต่อการเปลี่ยนแปลงเฉยๆ ซึ่งข้อดีของมันคือ Developer ทุกคนทำได้ง่าย และไม่ซับซ้อน
{% endhint %}

### 👍 ข้อดีในการทำงานกับระดับ Abstraction

![](/files/-Lsf6BoeIqd3wDFkNCET)

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

{% hint style="info" %}
**ข้อแนะนำ**\
ความหมายของการ **ทำงานกับระดับ Abstraction** ไม่ได้หมายถึง abstract class นะ แต่เป็นการเหมารวมของที่เป็น **ต้นแบบ** หรือเรียกอีกแบบว่า **Concept** เช่น **Abstract, Interface**
{% endhint %}

![](/files/-LnrS9NZIVN4qHkt77We)

เพราะการโค้ดของเราจะมีลักษณะของการทำ **Polymorphism** อยู่ภายในตัวเองอยู่แล้ว ดังนั้นมันจะสามารถรองรับการทำงานอื่นๆในอนาคตได้ทันที โดยที่เราเขียนโค้ดเพียงแค่ครั้งเดียวเท่านั้น เช่น เมื่อเราเพิ่มคลาส **สิงห์โต, วัว** และ **หมี**เข้าไป โค้ดเดิมที่ทำงานกับ Animal ที่เป็น Abstraction ก็จะรองรับเจ้าคลาสใหม่ๆพวกนั้นทันที โดยที่เราไม่ต้องไปแก้โค้ดอะไรทั้งสิ้นเลยนั่นเอง ตามรูปด้านล่าง

![](/files/-M0OJInvkuOrHWQ76w5R)

{% hint style="info" %}
**แนะนำให้อ่าน**\
ใครจำเรื่อง Polymorphism ไม่ได้แล้วให้กดกลับไปทบทวนได้จากลิงค์นี้เลย [💖 Polymorphism](https://saladpuk.gitbook.io/learn/beginner-1/oop/polymorphism)
{% endhint %}

## 😭 ใครช่วยแก้ปัญหานี้ได้บ้าง ?

ในกลุ่มของ **Creational Patterns** นี้มีพระเอกหลายตัวเลยที่จะมาช่วยแก้ปัญหาในการสร้าง object ซึ่งแต่ละตัวนั้น มันจะเหมาะกับปัญหาแต่ละแบบ ดังนั้นไปดูว่าแต่ละตัวมันช่วยแก้ปัญหาอะไรเลยละกัน

### [🏭 **Factory Method Pattern**](https://saladpuk.gitbook.io/learn/beginner-1/design-patterns/creational/factory-method-pattern)

> ช่วยสร้าง object ที่เหมาะสมกับสถานะการณ์ที่กำลังเป็นอยู่

### [🏭 **Abstract Factory Pattern**](https://saladpuk.gitbook.io/learn/beginner-1/design-patterns/creational/abstract-factory-pattern)

> ช่วยสร้างกลุ่มของ object ที่มีความเกี่ยวข้องกัน

### [☝️ **Singleton Pattern**](https://saladpuk.gitbook.io/learn/beginner-1/design-patterns/creational/singleton-pattern)

> ช่วยให้ object ตัวนั้นมีได้เพียงแค่ตัวเดียวเท่านั้น และใครๆสามารถเข้าถึงได้

### [🏗️ **Builder Pattern**](https://saladpuk.gitbook.io/learn/beginner-1/design-patterns/creational/builder-pattern)

> ช่วยสร้าง object ที่มีขั้นตอนในการสร้างอันวุ่นวายให้ง่ายขึ้น

### [🎎 **Prototype Pattern**](https://www.saladpuk.com/beginner-1/design-patterns/creational/prototype-pattern)\*\*\*\*

> ช่วยในการก๊อปปี้ object หนึ่ง ออกไปเป็นอีก object ได้แบบง่ายๆ

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

{% hint style="info" %}
คอร์สนี้กำลังค่อยๆเขียนอยู่ ใครที่ไม่อยากพลาดอัพเดทก็เข้าไปกดติดตามที่ลิงค์ [**Mr.Saladpuk**](https://www.facebook.com/mr.saladpuk) ได้เลย ส่วนใครที่อยากศึกษา pattern ตัวไหนล่วงหน้าก็ไปอ่านบทความเก่าได้ที่ลิงค์นี้ [🤴 Design Patterns](https://saladpuk.gitbook.io/learn/software-design/designpatterns) (อ่านแล้วเมากาวไม่รู้ด้วยนะ) **+ ในคอร์สนี้จะเริ่มอธิบาย Pattern แต่ละตัวจากกลุ่มนี้ก่อนนะครัช**
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.saladpuk.com/beginner-1/design-patterns/creational.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
