> For the complete documentation index, see [llms.txt](https://www.saladpuk.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.saladpuk.com/beginner-1/design-patterns/creational.md).

# 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 %}
