IT General
น้องๆ เคยเจอไหม โค้ดที่อ่านแล้วเหมือนโดนเอเลี่ยนเขียน? แก้บั๊กทีนึง ต้องรื้อทั้งโปรเจกต์? นั่นแหละคือฝันร้ายของโปรแกรมเมอร์ทุกคน ซึ่ง Clean Code คือทางออก!
Clean Code ไม่ใช่แค่เขียนให้มัน "ทำงานได้" แต่มันคือการเขียนโค้ดที่ "อ่านง่าย เข้าใจง่าย และแก้ไขง่าย" เหมือนเราเขียนเรียงความส่งอาจารย์ ไม่ใช่เขียนภาษาต่างดาวให้เพื่อนงงเล่น
สมัยผมทำร้านเน็ต SiamCafe.net เมื่อ 20 กว่าปีก่อน โค้ดเราไม่ได้สวยหรูอะไรหรอกครับ เน้นเร็ว เน้นใช้งานได้ แต่พอโปรเจกต์มันใหญ่ขึ้นเท่านั้นแหละ...นรกชัดๆ! แก้ตรงนี้ พังตรงนั้น ผมเลยเข้าใจว่า Clean Code มันสำคัญขนาดไหน
ลองคิดดูนะ ถ้าเราเขียนโค้ดแบบสปาเก็ตตี้ ใครมันจะกล้าแก้? ทีมงานใหม่เข้ามาก็ปวดหัว ลูกค้าเจอบั๊กก็โวยวาย สุดท้ายโปรเจกต์ก็พังไม่เป็นท่า
Clean Code ช่วยให้:
สรุปง่ายๆ Clean Code คือการลงทุนระยะยาว ที่จะช่วยให้โปรเจกต์ของเราเติบโตได้อย่างยั่งยืน
อันนี้ผมเจอมากับตัว สมัยก่อนตอนทำ SiamCafe.net มีช่วงนึงที่โค้ดมันเละมาก จนทีมงานไม่อยากเข้าไปยุ่งเลย พอมีบั๊กทีนึง ต้องเสียเวลาเป็นวันๆ กว่าจะแก้ได้
แต่พอเราเริ่มปรับมาใช้ Clean Code principles เวลาแก้บั๊กลดลงเยอะมาก จากวัน เหลือแค่ไม่กี่ชั่วโมง หรือบางทีก็แค่ไม่กี่นาที! ลองคิดดูว่าประหยัดค่าแรงไปได้เท่าไหร่ แถมทีมงานก็แฮปปี้ขึ้นเยอะด้วย
ก่อนจะไปถึงขั้นเทพ เรามาปูพื้นฐานกันก่อนนะน้องๆ เหมือนเราจะสร้างบ้าน ก็ต้องมีเสาเข็มที่แข็งแรง
ชื่อตัวแปร ชื่อฟังก์ชัน ชื่อคลาส ต้องสื่อความหมายให้ชัดเจน อย่าตั้งชื่อแบบ x, y, z หรือ tmp เพราะคนอื่น (รวมถึงตัวเราเองในอนาคต) จะงงว่ามันคืออะไร
// ไม่ดี
int d; // elapsed time in days
// ดีกว่า
int elapsedTimeInDays;
เห็นไหมครับ แค่เปลี่ยนชื่อตัวแปร ชีวิตก็ง่ายขึ้นเยอะ!
ฟังก์ชันที่ดี ควรจะสั้น กระชับ และทำหน้าที่อย่างเดียวเท่านั้น อย่าเขียนฟังก์ชันที่ยาวเป็นหน้ากระดาษ เพราะมันจะอ่านยาก และแก้ไขยาก
// ไม่ดี
void processOrder(Order order) {
// Validate order
// Calculate total
// Apply discount
// Save to database
// Send email
}
// ดีกว่า
void processOrder(Order order) {
validateOrder(order);
calculateTotal(order);
applyDiscount(order);
saveToDatabase(order);
sendEmail(order);
}
เห็นไหมครับ แค่แยกฟังก์ชันย่อยๆ ออกมา โค้ดก็ดูสะอาดตาขึ้นเยอะ แถมยังแก้ไขได้ง่ายขึ้นด้วย
หลายคนคิดว่า Comments คือเพื่อนแท้ แต่จริงๆ แล้ว Comments คือดาบสองคม ถ้าเขียนเยอะเกินไป มันจะรกโค้ด และทำให้โค้ดดูซับซ้อนกว่าเดิม
Comments ควรเขียนเมื่อ:
แต่ถ้าโค้ดมัน Clean พอ เราก็แทบจะไม่ต้องเขียน Comments เลย
ดูวิดีโอเพิ่มเติมเกี่ยวกับClean Code Principles Guide:
โอเค ทีนี้เรามาดูวิธีใช้งาน Clean Code principles กันบ้าง เริ่มจากง่ายๆ ก่อนเลย
ไม่ต้องรีบร้อนเปลี่ยนทุกอย่างในทีเดียว เริ่มจากไฟล์เล็กๆ หรือฟังก์ชันง่ายๆ ก่อนก็ได้ ค่อยๆ ปรับ ค่อยๆ เปลี่ยน จนมันกลายเป็นนิสัย
สมัยผมเริ่มทำ Clean Code ผมก็เริ่มจากไฟล์ที่ผมต้องแก้บ่อยๆ ก่อนเลย ค่อยๆ ปรับชื่อตัวแปร ปรับโครงสร้างฟังก์ชัน จนมันอ่านง่ายขึ้น แล้วค่อยขยายไปไฟล์อื่นๆ
Code Review คือการให้เพื่อนร่วมทีมมาช่วยดูโค้ดของเรา เพื่อให้ช่วยหาข้อผิดพลาด และแนะนำวิธีการปรับปรุง
Code Review เป็นเครื่องมือที่ทรงพลังมาก เพราะมันช่วยให้เราเรียนรู้จากคนอื่น และช่วยให้เราเห็นมุมมองใหม่ๆ ที่เราอาจมองข้ามไป
ปัจจุบันมีเครื่องมือมากมายที่ช่วยให้เราเขียน Clean Code ได้ง่ายขึ้น เช่น:
มาลงมือทำกันเลยครับน้องๆ ผมจะยกตัวอย่างง่ายๆ ให้เห็นภาพ
Refactoring คือการปรับปรุงโค้ดที่มีอยู่แล้ว โดยที่ไม่เปลี่ยนพฤติกรรมของโค้ด
เช่น เรามีฟังก์ชันที่ยาวเหยียด เราก็ Refactor โดยการแยกฟังก์ชันย่อยๆ ออกมา
// ก่อน Refactor
void processData(Data data) {
// Load data from file
// Validate data
// Transform data
// Save data to database
// Send notification
}
// หลัง Refactor
void processData(Data data) {
Data loadedData = loadDataFromFile();
Data validatedData = validateData(loadedData);
Data transformedData = transformData(validatedData);
saveDataToDatabase(transformedData);
sendNotification();
}
เห็นไหมครับ แค่ Refactor ฟังก์ชันเดียว โค้ดก็ดูสะอาดตาขึ้นเยอะ แถมยังแก้ไขได้ง่ายขึ้นด้วย
อันนี้สำคัญมาก อย่าขี้เกียจตั้งชื่อตัวแปร ชื่อฟังก์ชัน ชื่อคลาส ต้องตั้งให้สื่อความหมาย
// ไม่ดี
int a;
void f(int b) {
// ...
}
// ดีกว่า
int numberOfCustomers;
void calculateDiscount(int customerId) {
// ...
}
จำไว้ว่า ชื่อที่ดี คือชื่อที่บอกว่ามันคืออะไร และมันทำอะไร
ถ้าสนใจเรื่องการตั้งชื่อตัวแปร ลองดูบทความใน SiamCafe Blog ได้นะครับ
Unit Tests คือการทดสอบโค้ดของเราทีละส่วน เพื่อให้แน่ใจว่ามันทำงานได้อย่างถูกต้อง
Unit Tests ช่วยให้เรามั่นใจว่าโค้ดของเราจะไม่พังเมื่อเราแก้ไขมัน และมันยังช่วยให้เราเข้าใจโค้ดของเราได้ดีขึ้นด้วย
สมัยผมทำ SiamCafe.net แรกๆ ไม่ค่อยได้เขียน Unit Tests หรอกครับ เน้นเร็ว เน้นใช้งานได้ แต่พอโปรเจกต์มันใหญ่ขึ้นเท่านั้นแหละ...บั๊กเพียบ! แก้ตรงนี้ พังตรงนั้น ผมเลยเข้าใจว่า Unit Tests มันสำคัญขนาดไหน
แน่นอนว่า Clean Code ไม่ใช่ทางเลือกเดียวในการพัฒนาซอฟต์แวร์ แต่เป็นทางเลือกที่ดีที่สุดทางหนึ่ง
| คุณสมบัติ | Clean Code | Dirty Code |
|---|---|---|
| ความง่ายในการอ่าน | ง่ายมาก | ยากมาก |
| ความง่ายในการแก้ไข | ง่าย | ยาก |
| ความเร็วในการพัฒนา | อาจจะช้าในช่วงแรก แต่เร็วกว่าในระยะยาว | เร็วกว่าในระยะแรก แต่ช้าลงในระยะยาว |
| ค่าใช้จ่าย | ต่ำกว่าในระยะยาว | สูงกว่าในระยะยาว |
| ความสุขในการทำงาน | สูง | ต่ำ |
จากตารางจะเห็นได้ว่า Clean Code อาจจะทำให้เราเสียเวลามากขึ้นในช่วงแรก แต่ในระยะยาว มันจะช่วยให้เราประหยัดเวลา ประหยัดค่าใช้จ่าย และมีความสุขในการทำงานมากขึ้น
ลองแวะไปอ่านบทความอื่นๆ ที่ SiamCafe Blog ดูนะครับ มีเรื่อง IT อีกเยอะเลย
มาถึงตรงนี้ น้องๆ น่าจะพอเห็นภาพรวมของ Clean Code กันแล้วเนอะ แต่ไอ้ที่เรียนรู้มาทั้งหมดเนี่ย มันจะใช้ได้จริงก็ต่อเมื่อเราเอาไปลงมือทำจริงเท่านั้นแหละ สมัยผมทำร้านเน็ต SiamCafe เนี่ย เจอปัญหาโค้ดรกๆ มาเยอะแยะ บางทีแก้บั๊กทีนึง ใช้เวลาเป็นวันๆ เพราะโค้ดมันอ่านยากนี่แหละ
ประสบการณ์สอนให้รู้ว่า การเขียนโค้ดให้สะอาด ไม่ใช่แค่เรื่องของความสวยงาม แต่มันคือ "ความอยู่รอด" ของโปรเจกต์เลยนะ ลองคิดดูดิ ถ้าโค้ดมันเละเทะ แก้ไขยาก ใครมันจะอยากมาดูแลต่อ ยิ่งโปรเจกต์ใหญ่ๆ ยิ่งสำคัญเลย
เอาล่ะ มาดูกันว่ามีเทคนิคอะไรบ้างที่ผมใช้บ่อยๆ แล้วมันเวิร์คจริงๆ
อันนี้สำคัญมากๆ น้องๆ หลายคนชอบตั้งชื่อตัวแปรแบบมักง่าย เช่น x, y, tmp คือมันอาจจะเข้าใจได้ตอนที่เราเขียน แต่พอผ่านไปซักพัก กลับมาอ่านเองยังงงเลย
จำไว้ว่า ชื่อที่ดีต้องสื่อความหมายชัดเจน บอกได้ว่าตัวแปรนี้เอาไว้ทำอะไร เช่น customerName, orderTotalAmount อะไรแบบนี้
// แบบไม่ดี
int x = 0;
// แบบดี
int numberOfCustomers = 0;
อย่าพยายามยัดทุกอย่างลงไปในฟังก์ชันเดียว ให้แบ่งฟังก์ชันออกเป็นส่วนๆ เล็กๆ ที่ทำหน้าที่เฉพาะเจาะจง เวลาแก้บั๊ก หรือเพิ่มฟีเจอร์ มันจะง่ายกว่าเยอะ
สมัยผมทำระบบสมาชิกของ SiamCafe เนี่ย ฟังก์ชันใหญ่ๆ นี่ตัวดีเลย แก้ทีนึงกระทบไปทั้งระบบ
// แบบไม่ดี
function processOrder(order) {
// ตรวจสอบข้อมูล
// คำนวณราคา
// บันทึกลงฐานข้อมูล
// ส่งอีเมล
}
// แบบดี
function validateOrder(order) { ... }
function calculateTotal(order) { ... }
function saveOrderToDatabase(order) { ... }
function sendConfirmationEmail(order) { ... }
function processOrder(order) {
if (validateOrder(order)) {
const total = calculateTotal(order);
saveOrderToDatabase(order, total);
sendConfirmationEmail(order);
}
}
Comment ไม่ใช่ยาวิเศษ ที่จะทำให้โค้ดห่วยๆ กลายเป็นโค้ดดีๆ ได้ Comment ที่ดี ควรจะอธิบาย "เหตุผล" เบื้องหลังโค้ด ไม่ใช่แค่ "สิ่งที่" โค้ดทำ
ถ้าโค้ดมันอ่านยากจนต้องใส่ comment อธิบายเยอะๆ แสดงว่าโค้ดมันต้องปรับปรุงแล้วล่ะ
// แบบไม่ดี
// เพิ่มค่า x เข้าไป
x++;
// แบบดี
// เพิ่มจำนวนลูกค้าที่เข้ามาในร้าน เพื่อคำนวณโปรโมชั่น
numberOfCustomers++;
ช่วงแรกๆ อาจจะรู้สึกว่าเสียเวลา แต่ในระยะยาว มันจะช่วยประหยัดเวลาได้เยอะเลย เพราะเราจะใช้เวลาในการแก้บั๊ก และทำความเข้าใจโค้ดน้อยลง แถมยังทำให้คนอื่นทำงานร่วมกับเราได้ง่ายขึ้นด้วย
หลักการ Clean Code ใช้ได้กับทุกภาษาเลยน้อง เพราะมันเป็นเรื่องของวิธีคิด และการจัดระเบียบโค้ด ไม่ได้ขึ้นอยู่กับ syntax ของภาษา
ไม่เลย! Clean Code ยิ่งสำคัญกับโปรเจกต์ใหญ่ๆ เพราะโปรเจกต์ใหญ่ๆ จะมีคนทำงานร่วมกันเยอะ ถ้าโค้ดมันเละเทะ ก็จะยิ่งวุ่นวาย
มีเยอะแยะเลยน้อง ตั้งแต่ linters ที่ช่วยตรวจจับข้อผิดพลาด ไปจนถึง code formatters ที่ช่วยจัดระเบียบโค้ดให้อัตโนมัติ ลองหาเครื่องมือที่เหมาะกับภาษาที่เราใช้ดู
Clean Code ไม่ใช่แค่เทคนิคการเขียนโปรแกรม แต่มันคือ "ปรัชญา" ที่จะช่วยให้เราเป็นโปรแกรมเมอร์ที่ดีขึ้น เขียนโค้ดที่อ่านง่าย เข้าใจง่าย และดูแลรักษาง่าย ลองเอาไปปรับใช้กันดูนะน้องๆ แล้วจะรู้ว่ามันดีจริงๆ
อย่าลืมว่า การลงทุนในความรู้ด้าน Clean Code คือการลงทุนที่คุ้มค่าที่สุดอย่างหนึ่งของโปรแกรมเมอร์ทุกคน iCafeForex สนับสนุนให้ทุกคนพัฒนาตัวเองอยู่เสมอ
ติดตามบทความดีๆ เกี่ยวกับ IT ได้ที่ SiamCafe Blog นะครับ