เคล็ดลับ 12 ข้อสำหรับ การเขียนโค้ดให้ดีขึ้น

เคล็ดลับ 12 ข้อสำหรับ การเขียนโค้ดให้ดีขึ้น

การเขียนโค้ดที่ดูง่าย (Clean code) นั้นช่วยให้ซอฟต์แวร์ของเรามีความปลอดภัยมากขึ้น ง่ายต่อการบำรุงรักษา และมีประสิทธิภาพในระยะยาว ในบริบททางวิชาชีพ มันทำให้งานของเราเข้าใจง่ายสำหรับผู้อื่น สามารถทบทวน ดีบั๊ก (Debugs) และแก้ไขได้ง่ายขึ้น ในฐานะนักพัฒนาซอฟต์แวร์ เราไม่ได้เขียนโค้ดสำหรับเครื่องจักรเท่านั้น แต่เรายังเขียนสำหรับมนุษย์ด้วย

โค้ดที่ดูง่าย (Clean code) คืออะไร?

  1. อ่านได้ง่าย (Readability)

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

  1. ความเรียบง่าย (Simplicity)

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

  1. ความสื่อความหมาย (Expressiveness)

โค้ดควรสื่อความตั้งใจของนักพัฒนาอย่างชัดเจน นั่นหมายถึงการหลีกเลี่ยงการใช้ "Magic numbers (ค่าตัวเลขในโค้ดที่ไม่มีความหมายชัดเจนหรือปรากฏหลายครั้ง)" และรหัสลับที่ยากต่อการเข้าใจ และแทนที่ด้วยค่าคงที่และฟังก์ชันที่มีชื่อดีและอธิบายได้ชัดเจนว่ามันทำอะไร

  1. ความสามารถทดสอบได้ (Testability)

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

ตอนนี้ลองมาดูเคล็ดลับ 12 ข้อสำหรับการเขียนโค้ดที่สะอาด เพื่อความเรียบง่าย ตัวอย่างโค้ดจะใช้ JavaScript

1. การตั้งชื่อที่ดีขึ้น

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

// Bad practice
let firstname = 'John';
let LastName = 'Doe';
function calculateage(birthYear) {...}
class people {}

// Good practice
let firstName = 'John';
let lastName = 'Doe';
function calculateAge(birthYear) {...}
class People {}

การเริ่มชื่อฟังก์ชันด้วยคำกริยา (Verbs) จะทำให้โค้ดของคุณชัดเจนและเข้าใจได้ง่ายขึ้น เป็นการบ่งชี้ว่าฟังก์ชันกำลังดำเนินการอะไร

// Not recommended
function name() {...}

// Recommended
function getName() {...}

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

// Not recommended
let d = new Date();
let y = d.getFullYear();
​
// Recommended
let currentDate = new Date();
let currentYear = currentDate.getFullYear();

2. ทำให้ฟังก์ชันของคุณมีขนาดเล็ก เน้นคุณภาพ

หลักการทั่วไปที่ดีคือฟังก์ชันควรทำสิ่งหนึ่งที่ทำได้ดี หากฟังก์ชันหนึ่งทำงานหลายอย่าง ก็เป็นสัญญาณว่าจำเป็นต้องแบ่งออกเป็นฟังก์ชันที่เล็กลงและเน้นมากขึ้น

// Not recommended
function handleDeveloper() {
  // code to validate developer data
  // code to save developer data
  // code to send a welcome email
}

// Recommended
function validateDeveloperData() {...}
function saveDeveloperData() {...}
function sendWelcomeEmail() {...}

3. หลีกเลี่ยงการทำซ้อนใน (Nesting) ที่ลึกเกินไป

โค้ดที่ซ้อนในลึก (Deep nesting) อาจอ่านและทำความเข้าใจได้ยาก พยายามทำให้โค้ดของคุณแบนราบที่สุด

// Bad practice
if (condition1) {
  if (condition2) {
    if (condition3) {
      // Do something
    }
  }
}

// Good practice
if (!condition1) return;
if (!condition2) return;
if (!condition3) return;
// Do something

4. ใช้ความคิดเห็น (Comments) เท่าที่จำเป็น

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

// Bad practice
let x = 10; // setting x to 10
​
// Good practice
// If we reach this point, the user is eligible for the discount
let isDiscountEligible = true;

5. ทำฟังก์ชันของคุณให้เพียว

ฟังก์ชันเพียว (Pure functions) คือฟังก์ชันในการเขียนโปรแกรมที่ให้เอาต์พุต (Out put) เดียวกันสำหรับอินพุต (In put) ชุดเดียวกัน ไม่ว่าจะเรียกกี่ครั้งก็ตาม ฟังก์ชันเหล่านี้ไม่รักษาสถานะใดๆ ระหว่างการประมวลผลหรือสร้างผลข้างเคียงใดๆ ซึ่งหมายความว่าฟังก์ชันเหล่านี้จะไม่เปลี่ยนแปลงหรือส่งผลต่อข้อมูลหรือตัวแปรภายนอก ฟังก์ชันเพียวจะทำให้โค้ดของคุณทดสอบและดีบั๊กได้ง่ายขึ้น

// Bad practice
let age = 25;
​
function incrementAge() {
  age++;
}

// Good practice
function incrementAge(age) {
  return age + 1;
}

6. จำกัดขอบเขตของตัวแปร

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

// Bad practice
let counter = 0;
function incrementCounter() {
  counter++;
}

// Good practice
function createCounter() {
  let counter = 0;
  
  function incrementCounter() {
    counter++;
  }
  
  return incrementCounter;
}

7. จัดการกับข้อผิดพลาด (Errors) ให้ดี

การจัดการข้อผิดพลาดเป็นส่วนสำคัญในการเขียนโค้ดที่ดูง่ายและมีประสิทธิภาพ เป็นการดีกว่าเสมอที่จะคาดการณ์ข้อผิดพลาดที่อาจเกิดขึ้นและจัดการกับข้อผิดพลาดเหล่านั้นอย่างดี

// Bad practice
function divideNumbers(x, y) {
  return x / y;
}

// Good practice
function divideNumbers(x, y) {
  if (y === 0) {
    throw new Error('Cannot divide by zero');
  }
  return x / y;
}

8. ใช้หลักการ DRY (Don't Repeat Yourself) หรือ ไม่ควรทำซ้ำ

หลีกเลี่ยงการเขียนโค้ดซ้ำกัน หากคุณพบว่าตัวเองเขียนโค้ดเดียวกันในหลายจุด ให้พิจารณาสร้างฟังก์ชันขึ้นมา

// Bad practice
let x = y * 10;
let z = w * 10;
​
// Good practice
function multiplyByTen(num) {
  return num * 10;
}
let x = multiplyByTen(y);
let z = multiplyByTen(w);

9. กำหนดค่าคงที่สำหรับตัวเลข (Number) และสตริง (Strings) ที่คาดเดาความหมายยาก

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

// Bad practice
if (status === 1) {
  // Do something
}
​
// Not recommended
const salary = 40 * 15.50;
// Good practice
const ACTIVE_STATUS = 1;
if (status === ACTIVE_STATUS) {
  // Do something
}
​
// Recommended
const HOURS_PER_WEEK = 40;
const HOURLY_RATE = 15.50;
const salary = HOURS_PER_WEEK * HOURLY_RATE;

10. จำกัดพารามิเตอร์ของฟังก์ชัน

หลีกเลี่ยงการใช้พารามิเตอร์จำนวนมากในฟังก์ชัน เนื่องจากอาจทำให้โค้ดของคุณสับสนและยากต่อการบำรุงรักษา หากคุณต้องส่งค่าหลายค่า ให้พิจารณาใช้อ๊อบเจ็ค (Object)

// Not recommended
function displayDeveloper(firstName, lastName, address, phoneNumber, email) {...}
​
// Recommended
function displayDeveloper(developer) {...}

โดยการส่งอ๊อบเจ็ค Developer เพียงอันเดียว เราสามารถกำหนดขอบเขตข้อมูลที่เกี่ยวข้องและทำให้การเรียกใช้ฟังก์ชันง่ายขึ้น

11. งดการใช้ Dependenciesให้น้อยที่สุด

การใช้ Dependencies ที่มากเกินไปอาจทำให้โค้ดของคุณยากต่อการบำรุงรักษาและการทดสอบ ควรใช้ให้น้อยที่สุด และจัดการอย่างเหมาะสม

// Not recommended
class MyService {
    constructor() {
        this.dep1 = new Dependency1();
        this.dep2 = new Dependency2();
        this.dep3 = new Dependency3();
    }
    // ...
}

// Recommended
class MyService {
    constructor(dep) {
        this.dep = dep;
    }
}

12. ปรับปรุงโค้ดอย่างสม่ำเสมอ

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

// Before refactoring
function processOrder(order) {
    validateOrder(order);
    calculateTotal(order);
    printReceipt(order);
}

// After refactoring
function processOrder(order) {
    if (!isValid(order)) {
        throw new Error('Invalid order');
    }
    let total = calculateTotal(order);
    printReceipt(order, total);
}

บทสรุป

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

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

ขอให้สนุกกับการเขียนโค้ดนะ!

ที่มา: https://zacharylee.substack.com/p/12-quick-tips-for-writing-clean-code

Arnon Kijlerdphon

Arnon Kijlerdphon

Board game & Plant-based & Minimalist, it's all my life.
Bangkok, Thailand