เคล็ดลับ 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