# Uncle Bob - Clean Code

บทความนี้เป็นการสรุปเนื้อหาจากวีดีโอของลุงบ๊อบ หรือ [**Robert C. Martin**](https://en.wikipedia.org/wiki/Robert_C._Martin) มหาเทพในวงการคอมพิวเตอร์ ที่ลุงแกมาพูดถึงการทำ **Clean Code** หรือแปลเป็นไทยแบบกำปั้นทุบดินว่า **การทำโค้ดให้สะอาด** กัน เพื่อให้เห็นถึงความสำคัญและประโยชน์ของการทำ Clean Code นั่นเองครัช โดยเนื้อหาถูกแบ่งออกเป็น 6 วีดีโอ ดังนั้นแมวน้ำก็เขียนแตกออกมาเป็น 6 บทความเช่นกันนะขอรับ

{% hint style="success" %}
**แนะนำให้อ่าน**\
บทความนี้เป็นส่วนหนึ่งของบทคอร์ส [👶 **Clean Code**](https://www.saladpuk.com/basic/clean-code) หากเพื่อนๆแมวน้ำสนใจศึกษาเรียนรู้ว่าการทำ Clean Code ว่ามันคืออะไร? มีอะไรบ้าง? บลาๆ ก็สามารถกดที่ชื่อบทความสีฟ้าๆเข้าไปอ่านได้เลยครัช
{% endhint %}

## 🤔 โค้ดดีไม่ดีดูไง ?

การดูว่าโค้ดเราดีหรือเปล่าให้ดูจาก **คำด่าต่อนาที** ตอนทำ **Code Review** เพราะโค้ดต่อให้มันทำงานได้ดียังไงก็ตาม แต่เมื่อมีการขอเพิ่มหรือแก้ไข features เกิดขึ้น แล้วคนเขียนโค้ดไม่สามารถเข้าใจโค้ดเหล่านั้นได้ โค้ดเหล่านั้นก็ไม่มีประโยชน์ เพราะมันกำลังจะเป็นโค้ดที่ตายแล้ว ดังนั้น **โค้ดที่เข้าใจได้ง่าย เพิ่มเติมต่อยอดได้ง่าย** ถึงเป็นโค้ดที่มีประโยชน์ต่อทีมทำงานมากกว่านั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MESo2IiNQ8fdiuO2POS%2F-MESsO5zDhnT9ZtmvxL-%2Fimage.png?alt=media\&token=e6286e23-0bbd-4082-b7ae-b17e2bef7829)

> โค้ดที่เขียนวันนั้น มีแต่ผมกับพระเจ้าเท่านั้นที่เข้าใจ 😎 ... แต่ตอนนี้ เหลือแค่พระองค์เท่านั้นละ 😐

{% hint style="success" %}
**แนะนำให้อ่าน**\
ต่อให้โค้ดนั้นมันเขียนไว้เทพแค่ไหนก็ตาม แต่ไม่มีใครเข้าใจมันได้เลยแม้แต่คนในทีม หรือตัวเราในอนาคต มันก็คือมะเร็งร้ายที่จะทำให้ซอฟต์แวร์มีปัญหาในระยะยาว ถ้าสนใจอยากรู้ว่าทำไม? อ่านได้จากบทความ [**ปัญหาที่ใหญ่ที่สุดในการทำซอฟต์แวร์**](https://www.saladpuk.com/v/tips/why-software-fail) ได้เลยครัช
{% endhint %}

## 🤓 โลกเราอยู่ได้เพราะซอฟต์แวร์

ของทุกอย่างในโลกนี้อยู่ได้ด้วยซอฟต์แวร์!! เพราะถ้าไม่มีซอฟต์แวร์ มนุษย์แทบจะทำอะไรไม่ได้เลย ถอนเงิน ซื้อของ เติมเงิน คุยกับเพื่อนระยะไกล รถไร้คนขับ กฎหมาย ภาษี บลาๆ ซึ่งระบบทั้งหมดที่ว่ามา **การเขียนโค้ดผิดเพียงบรรทัดเดียว อาจทำให้คนนับพันตาย หรือเศรษฐกิจล่มได้เลย** . . . แล้วใครละที่เป็นคนเขียนโค้ดพวกนั้น? . . .ถ้าไม่ใช่พวกเรา

> การเขียนโค้ดโง่ๆเพียงบรรทัดเดียว อาจทำให้ธุรกิจใหญ่ๆพังได้ในข้ามคืน

คนเขียนซอฟต์แวร์คือคนที่ถูกเรียกว่าเป็น **มืออาชีพด้านซอฟต์แวร์** ดังนั้นคนที่จะเป็น Software Professional ตัวจริงจะต้องไม่พลาดเรื่องเหล่านี้ แล้วเราจะทำมันได้ยังไง? ลุงบ๊อบแกเลยตอบว่า

> 🧓 เราต้องมีมาตรฐานในการทำงานไง และหนึ่งในมาตรฐานที่ว่าคือ **การทำ Clean Code** งุยจ๊ะ

## 🤔 Clean Code คือไย ?

มีมหาเทพหลายคนในวงการให้คำนิยามไว้เต็มไปหมดเลย แต่สิ่งที่แมวน้ำชอบที่สุดคือ 💖 **การใส่ใจในโค้ดที่ตัวเองเขียน ดุจว่าเขาคือลูกของเรา** ดังนั้นโค้ดที่เราใส่ใจมันจะถูกทำทุกอย่างให้ อ่านเข้าใจได้ง่าย มีความเป็นระเบียบ แก้ไขเพิ่มเติมได้สะดวก และ 💖 **ทุกบรรทัดที่เราอ่าน คือสิ่งที่เราคาดหวังว่าโค้ดมันควรจะเป็นแบบนั้น** (จริงๆนะถ้าคุณไม่ได้เข้าใจว่าทำไมเราต้องทำ Clean Code ผมโคตรอยากให้คุณอ่านบทความ [**ปัญหาที่ใหญ่ที่สุดในการทำซอฟต์แวร์**](https://www.saladpuk.com/v/tips/why-software-fail) จริงๆ เพราะมันคือจุดชี้เป็นชี้ตายของบริษัทซอฟต์แวร์เลยให้ตายซิ)

> ต่อให้โค้ดนั้นจะเทพแค่ไหนก็ตาม แต่ไม่มีใครเข้าใจมันได้เลย ... เมื่อ requirement change มันก็คือขยะดีๆนี่เอง แต่ในทางกลับกัน ถ้าคุณเอาโค้ดที่ทำงานไม่ได้มาให้ แต่คนอ่านดูแล้วรู้ว่ามันพยายามจะทำอะไร เขาจะสามารถแก้ไขเพิ่มเติมจุดที่มันยังขาดได้

## 🤨 Clean Code ทำไงบ้าง ?

### 💖 Intent

**โค้ดที่เขียนจะต้องแสดงเจตนาของมันชัดเจน ว่ามันถูกสร้างขึ้นมาทำไม?** เช่น ลองอ่านโค้ดแบบแย่ๆด้านล่างดู แล้วลองเดาดิ๊ว่า จริงๆมันต้องการทำอะไร?

![https://www.youtube.com/watch?v=7EmboKQH8lM\&t=2409s](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MESvmZVmhx1hTlvRqQC%2F-MET2gy7DeOStPCLMAgh%2Fimage.png?alt=media\&token=febcb0a2-e0b6-49b0-8ab1-83da5950b931)

จะเห็นว่าโค้ดที่แย่ๆ มันจะทำให้เราเสียเวลาอ่านเยอะม๊วก แทบจะต้องไล่ตามอ่านทีละบรรทัด เพื่อแกะว่าไอ้คนเขียนมันพยายามจะทำอะไร และบางทีก็อ่านทั้งหมดก็ยังต้องกลับมาอ่านซ้ำเพราะไม่เข้าใจ ... แล้วลองเทียบกับโค้ดที่ถูก Clean แล้วดูบ้างดิ๊

![https://www.youtube.com/watch?v=7EmboKQH8lM\&t=2965s](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MESvmZVmhx1hTlvRqQC%2F-MET485-BpKwqgUw7gnD%2Fimage.png?alt=media\&token=888f6c80-5361-472d-bf27-990f5a8e47a7)

จะเห็นว่าโค้ดที่ถูก Clean แล้ว ต่อให้เราไม่รู้เรื่องมาก่อนเลยว่ามันคืออะไร แต่พออ่านเราก็จะรู้ว่า method นี้จะส่ง html กลับไป และจะเติมข้อมูลอะไรซักอย่างให้ถ้าเป็นหน้าสำหรับ Test หรือจริงๆ **แค่อ่านชื่อ method เราก็จะรู้เจตนาของมัน** ว่ามันเป็นการสร้างหน้าเพจสำหรับเอาไปแสดงผลซักอย่างนั่นเอง

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

จากที่ว่ามาเลยมีข้อแนะนำการเขียน method แบบง่ายๆคือ&#x20;

> **โค้ดทั้งหมดในเมธอดควรแสดงให้เห็นภายใน 1 หน้าจอได้ทั้งหมด เกินกว่านั้นถือว่าแย่**

### 💡 Extract method

ในบางทีโค้ดที่เราเขียนก็จะยาวเป็นหางว่าว อาจจะเป็น 1,000 บรรทัดหรืออะไรก็ตามแต่ บ่อยครั้งที่เราจะเห็นโค้ดที่คล้ายๆกันอยู่ในหลายๆที่ ซึ่งตามหลักจริงๆเราไม่ควรทำแบบนั้น ดังนั้นลุงบ๊อบเลยเสนอว่า

> 🧓 ให้เราทำการแตกเป็นเมธอดย่อยๆ (Extract method) ไปเรื่อยๆ แล้วทำการจัดกลุ่มมันดีๆ เผลอๆเราก็จะได้ class ใหม่ที่เป็นตัวระบบจริงๆโดยไม่รู้ตัวก็ได้ โดยหัวใจหลักของการแตกเมธอดย่อยคือการทำ [**(SRP) Single Responsibility Principle**](https://www.saladpuk.com/basic/solid/srp) **นั่นเอง**

![สีเหลืองคือ method ที่เราทำการ extract แล้ว จัดกลุ่มจนได้คลาสใหม่](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-MET8Dav9g767GXzJCM9%2F-METB6nd_gQanSX9NCug%2Fimage.png?alt=media\&token=7893c09b-d235-4166-97cd-f8463c61a1a8)

{% hint style="success" %}
**แนะนำให้อ่าน**\
สำหรับคนที่สนใจอยากรู้จักว่า [**(SRP) Single Responsibility Principle**](https://www.saladpuk.com/basic/solid/srp) คืออะไรก็ให้กดที่ชื่อมันได้เลย ซึ่งมันเป็นหนึ่งในหลักการออกแบบขั้นพื้นฐานที่โปรแกรมเมอร์ควรจะต้องรู้ แต่ถ้าใครสนใจอยากดูหลักการออกแบบพื้นฐานทั้งหมดก็สามารถไปอ่านได้จากลิงค์ตัวนี้ครัช [👦 **SOLID Design Principles**](https://www.saladpuk.com/basic/solid)
{% endhint %}

### 🏭 Method

#### 🍰 Arguments

เมธอดที่ดีที่สุดคือไม่ต้องมี argument เลย เพราะคนใช้มีหน้าที่แค่เรียกใช้ก็พอ แต่ถ้าจะต้องมี ไม่ควรมีเกิน 1\~3 ตัว โดยลุงบ๊อบแกให้เหตุผลว่า

> 🧓 ของที่ส่งไปให้กับเมธอด มันคือของที่มีความเกี่ยวข้องกัน ดังนั้นถ้าเรามีสิ่งที่เกี่ยวข้องกันเกิน 3 อย่างนั่นหมายความว่า มันควรจะอยู่ในรูปแบบของคลาสแล้ว ดังนั้นให้ส่งมาทั้งคลาสเลย (แมวน้ำเสริมให้ว่าทำเป็น model แล้วส่งไปกะดั๊ย)

#### 🚩 Flag argument

เวลาออกแบบเมธอดนั้น **ไม่ควรจะต้องรับ Flag argument เข้าม**า หรือพูดให้เข้าใจง่ายๆคือ **อย่าให้เมธอดต้องรับ Boolean เข้ามา**นั่นเอง โดยลุงบ๊อบให้เหตุผลว่า

> 🧓 ถ้าเราส่ง boolean เข้าไปใน method นั่นหมายความว่าเราจะต้องมี if อยู่ข้างใน ดังนั้นทำไมไม่แยกเป็นเมธอด 2 ตัวที่ทำงานแยกกันเลยล่ะ? (ไม่ผิดกฎ [SRP ](https://www.saladpuk.com/basic/solid/srp)ด้วย) หรือลองจิตนาการดูเวลาเรียกใช้เมธอดแล้วเจอแบบนี้ SimpleMethod(5,3,7, true) คำถามคือ true คืออะไร? คนอ่านก็จะ งง และต้องเสียเวลาไปไล่ดูการทำงานข้างในเมธอดนั้นๆอีกที ถึงจะรู้ว่าเมื่อไหร่ควรส่ง true เมื่อไหร่จะส่ง false

#### 👻 Output argument

เวลาออกแบบเมธอดนั้นไม่ควรมีการรับ argument ที่เอาไว้สำหรับ return ค่ากลับนอกเหนือจาก return type ของเมธอดเอง โดยลุงบ๊อบให้เหตุผลว่า

> 🧓 สิ่งที่ส่งเข้าไปเป็น argument ของเมธอดมันจะเป็นสิ่งที่สอดคล้องกันทั้งหมดอยู่แล้ว แต่ output argument จะเป็นสิ่งเดียวที่ไม่สอดคล้องกัน ดังนั้นเมื่อเราอ่านโค้ดเราจะ งง เพราะเราจะพบของที่มันต่างจากพวก แล้วเราต้องเสียเวลาไปไล่ตามหาว่าเจ้าตัวนี้คืออะไรอีกด้วย เช่น Print(line1, line2, line3, banaSakabra) แค่อ่านปุ๊ปเราก็จะเอ๋อแดร๊กว่า banaSakabra คือไรฟระ? เราจะเป็นต้องไปสนใจมันป่ะ? โค้ดมันถูกหรือยังฟระ? หรือต่อให้เราไม่สนใจแต่มันก็จะคาใจอยู่ดี ทำให้เราไม่สามารถ focus ต่อได้นั่นเอง

### 🔀 Switch case

ไม่ควรใช้ `switch case` keyword โดยลุงบ๊อบให้เหตุผลว่า

> 🧓 สาเหตุหลักๆคือ
>
> 1. Switch statements มันรับผิดชอบมากกว่า 1 อย่าง (ละเมิดกฎ [SRP](https://www.saladpuk.com/basic/solid/srp)) ดังนั้นของหลายๆอย่างจะไปผูกติดกับมัน
> 2. ปรกติ switch statements ถ้าใช้กับ object เรานิยมใช้กับของที่เป็น hierarchy ดังนั้นเวลาที่ต้องแก้ hierarchy เหล่านั้นมันก็จะต้องไปไล่แก้แต่ละ case ที่อยู่ใน switch เหล่านั้น
> 3. ในบาง case มันอาจจะไปเรียกใช้งาน module อื่น ทำให้มันเกิด Dependency กับไฟล์ที่ใช้ switch ได้ง่ายมาก ทำให้พวก .jar, .dll ของเราขาดความสามารถในการ delopy ได้แบบอิสระ เพราะทุกครั้งที่ dependency ที่เราเรียกใช้มีการอัพเดทเกิดขึ้น เราจะต้อง build ใหม่ deploy ใหม่ทุกครั้งนั่นเอง

> 🧓 จากเหตุผลที่ให้ไปทั้งหมด สามารถแก้ได้โดยการทำ Polymorphysm อยู่แล้ว ดังนั้นเราก็สามารถแยกแต่ละ case ให้ไปอยู่ในคลาสลูกที่เหมาะสมได้ ดังนั้นเวลาที่พฤติกรรมเปลี่ยน เราก็แค่แก้ไขคลาสลูกที่ดูแลพฤติกรรมตัวนั้นก็พอ หรืออย่างมากก็เพิ่มคลาสลูกตัวใหม่เท่านั้น ซึ่งไม่ทำให้โค้ดเดิมถูกแก้เลย ซึ่งเข้ากับหลัก **(OCP) Open/Closed Principle**  อีกด้วย

{% hint style="success" %}
**แนะนำให้อ่าน**\
[**(OCP) Open/Closed Principle**](https://www.saladpuk.com/basic/solid/ocp) ก็เป็นหนึ่งในหลักการออกแบบพื้นฐานที่เหล่าโปรแกรมเมอร์ควรจะต้องรู้ ถ้าสนใจก็กดที่ชื่อมันไปอ่านได้เบยขอรับ
{% endhint %}

### 🤕 Side effects

#### 💣 Output argument

สิ่งที่เป็น output จาก method ไม่ควรมีผลข้างเคียง (side effect) เช่น ผลลัพท์ที่ได้จากการอ่านไฟล์ ควรจะต้องนำมาใช้งานได้เลย ไม่ใช่จะใช้งานได้เฉพาะภายในช่วงที่ยังเปิด Stream อยู่เท่านั้น โดยลุงบ๊อบให้เหตุผลว่า

> 🧓 เวลาที่เราเรียกเมธอดเพื่อเอาผลลัพท์มันออกมาใช้ เราอยากจะเอาไปใช้เมื่อไหร่ก็ได้ ไม่จำเป็นต้องเป็นเดี๋ยวนั้น และตอนจะใช้มันควรจะต้องใช้ได้เสมอ ไม่ใช่เรียกได้บ้างไม่ได้บ้าง เพราะไม่อย่างนั้น developer จะ งง ว่าเกิดอะไรขึ้น และหลายๆคนน่าจะเคยเจอว่า เราต้องเสียเวลาตั้งหลายวันเพื่อแก้ bug แค่สลับบรรทัดกัน 2 บรรทัด ก็ทำงานได้โดยไม่รู้เหตุผลชิมิ นั่นแหละปัญหาจาก output argument

ดังนั้นวิธีการแก้ปัญหา output argument ที่มี side effect นั่นคือการ จัดการ side effect ให้หมดภายในเมธอดนั้นๆก่อน ค่อยส่งออกมันเป็น output ให้คนเรียกใช้สามารถใช้งานได้อย่างสบายใจ

#### ⚔️ Command & Query separation

โดยปรกติการทำงานต่างๆเราสามารถแยกมันออกเป็น 2 เรื่องคือ

1. **Command** - เป็นการสั่งให้มันทำงานอะไรซักอย่าง แล้วมัน**ทำให้ state ของระบบเปลี่ยน**
2. **Query** - เป็นการสั่งให้มันไป**เอาอะไรซักอย่างกลับมา**ให้ และ **ต้องไม่เปลี่ยน state ของระบบเลย**

ดังนั้นทุกครั้งที่เราเขียนเมธอดเราก็ควรที่จะยึดตามหลัก Command & Query นี้ด้วยคือ

* **เมธอดที่ไม่มี return type (void method)** - ตรงกับ Command ซึ่งเมื่อเราเรียกใช้ เราจะคาดหวังว่ามันต้องไปทำอะไรซักอย่างกับระบบ ซึ่งจะทำให้ state ของระบบเปลี่ยนแน่ๆ เพราะเราสั่งให้มันทำงาน แต่ไม่ต้องการอะไรกลับมา
* **เมธอดที่มี return type** - ตรงกับ Query เพราะมันไปเอาอะไรซักอย่างกลับมาให้เรา ดังนั้นเมื่อเราเรียกใช้งาน เราจะคาดหวังว่า **มันต้องไม่เกิดอะไรขึ้นกับระบบเรา** เพราะมันแค่ไปเอาของกลับมาให้เราดูเท่านั้น&#x20;

โดยลุงบ๊อบแกให้เหตุผลว่า

> 🧓 Command & Query เป็นสิ่งที่ใช้กันบ่อยและรู้จักกันกว้างขวางมาก ดังนั้นถ้าทำให้ของที่เป็นลักษณะเดียวกันให้เหมือนกัน จะทำให้ developer จำง่ายขึ้น ทำงานง่ายขึ้น และคาดหวังได้ว่าเมื่อไหร่จะเกิด state change และเมื่อไหร่ไม่เกิดนั่นเอง

### 🚨 Exception over Error Code

เวลาที่เกิดข้อผิดพลาดขึ้นให้ส่ง exception ไปเลย อย่าไปส่งเป็น Error Code โดยลุงบ๊อบให้เหตุผลว่า

> 🧓 ถ้าเราไม่ throw exception ไปเลย นั่นหมายความว่า เราต้องเขียนโค้ดเพิ่มขึ้นเพื่อระบุ Error Code ที่มันจะเกิดขึ้น ดังนั้นงานจะงอกเยอะขึ้น และเราต้องไปคอยจัดการกับ Error Code แต่ละแบบว่ามันเกิดแบบนี้ขึ้นเพราะอะไรได้ยากขึ้นอีกด้วย แทนที่จะเห็นเลยว่าจะเกิดเรื่องอะไร บรรทัดไหน

![ตัวอย่างการส่ง Error Code จะเห็นว่าเราต้องมาคอยตั้งเงื่อนไขต่างๆอีกว่าเมื่อไหร่ จะส่ง Error code อะไรกลับไป](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-METbxsq7x6U4bZpTmvm%2F-METfNIVlh-cY_A6j-Ik%2Fimage.png?alt=media\&token=ca6f0a6b-54f3-4353-b4e6-6367e7717099)

### 📝 DRY

(DRY) Don't Repeat Yourself หรือพูดง่ายๆคือ **อย่าไปทำของเดิมๆซ้ำๆ** โดยปรกติเรามักจะพูดถึงการเขียนโค้ดแบบเดียวกันเด๊ะๆ หลายๆจุด ซึ่งโดยปรกติ developer มักจะ copy โค้ดส่วนนั้นไปวางในที่ต่างๆที่มันมีการทำงานเหมือนๆกันนั่นเอง โดยลุงบ๊อบให้เหตุผลว่า

> 🧓 โค้ดที่เรา copy ไป มันอาจจะเผลอติดของที่เราไม่ต้องการตามไปด้วย แล้วบางทีเราก็ลืมลบมันออก ทำให้ชนรุ่นหลังบางทีก็มา copy โค้ดตัวนี้ไปวางที่อื่นต่ออีกที โดยที่ไม่รู้ว่าเจ้าตัวนี้่ไม่จำเป็นต้องก๊อปไปก็ได้นะ ดังนั้นมันก็จะมีขยะโดนก๊อปไปก๊อปมาอยู่เต็มไปหมดนั่นเอง และถ้าเงื่อนไขการทำงานมันเปลี่ยน เราก็ต้องไล่ตามแก้ทุกๆจุดเช่นกัน

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

## 🙌 ส่งท้ายบท

> 🧓 เราไม่มีวิธีพิสูจน์ว่าซอฟต์แวร์มันทำงานถูกต้องหรือเปล่า แต่เราสามารถทดสอบมันได้ ดังนั้นเราทำได้แค่ทดสอบมัน จนเราหาข้อผิดพลาดไม่เจอเท่านั้น แต่ก็ไม่ได้หมายความว่ามันทำงานถูก 100% แค่เรายังไม่เจอข้อผิดพลาดตัวอื่นๆเท่านั้นเอง
>
> We can't proof our software correct, We demonstrate that it not incorrect by surrounding it with tests.

ของบางอย่างแมวน้ำก็ไม่ได้ลงรายละเอียดให้นะ เพราะมันถูกเขียนไว้ใน [👶 **Clean Code**](https://www.saladpuk.com/basic/clean-code) ตัวหลักอยู่แล้ว ดังนั้นถ้าสนใจก็ไปกดอ่านเอาเองเด้อ

บทความนี้ยังไม่จบอย่างที่บอกว่ามันจะแบ่งเป็น 6 ส่วน นี่เป็นแค่ตอนที่ 1 เท่านั้นเอง ดังนั้นตามอ่านกันยาวๆต่อได้จากบทความหลัก หรือไม่อยากพลาดก็ติดตามได้จาก [**Facebook: Mr.Saladpuk**](https://www.facebook.com/mr.saladpuk) ฮั๊ฟ

{% hint style="success" %}
**แนะนำให้อ่าน**\
ในบทความถัดๆไปเราจะเจอหลักในการออกแบบเยอะม๊วก ดังนั้นแมวน้ำแนะนำให้รู้จักหลักในการออกแบบพื้นฐาน 5 ตัว โดยเพื่อนๆสามารถไปอ่านได้จากลิงค์นี้ครัช [👦 **SOLID Design Principles**](https://www.saladpuk.com/basic/solid)
{% endhint %}

## 🎥 วีดีโอลุงบ๊อบ

{% embed url="<https://www.youtube.com/watch?v=7EmboKQH8lM>" %}
