Clean Code
Meaningful Names
การตั้งชื่อที่มีความหมายชัดเจน ทำให้โค้ดอ่านง่ายและเข้าใจได้ทันที
javascript
// Bad
const d = new Date();
const n = "John";
const arr = [1, 2, 3];
// Good
const currentDate = new Date();
const userName = "John";
const numberList = [1, 2, 3];
Single Responsibility
ฟังก์ชันหรือคลาสควรมีหน้าที่เดียวที่ชัดเจน
javascript
// Bad
function handleUser(user) {
validateUser(user);
saveToDatabase(user);
sendEmail(user);
}
// Good
function validateUser(user) { /* ... */ }
function saveUser(user) { /* ... */ }
function notifyUser(user) { /* ... */ }
function handleNewUser(user) {
validateUser(user);
saveUser(user);
notifyUser(user);
}
DRY (Don't Repeat Yourself)
หลีกเลี่ยงการเขียนโค้ดซ้ำซ้อน นำโค้ดที่ใช้บ่อยมาทำเป็นฟังก์ชัน
javascript
// Bad
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
function validateUserEmail(user) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(user.email);
}
// Good
function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
function validateEmail(email) {
return isValidEmail(email);
}
function validateUserEmail(user) {
return isValidEmail(user.email);
}
Small Functions
ฟังก์ชันควรมีขนาดเล็ก ทำหน้าที่เดียว และมีความชัดเจน
javascript
// Bad
function processOrder(order) {
let total = 0;
for (const item of order.items) {
total += item.price * item.quantity;
}
const tax = total * 0.1;
total += tax;
order.total = total;
const db = connectToDatabase();
db.save(order);
const email = createEmailTemplate(order);
sendEmail(order.email, email);
}
// Good
function calculateSubtotal(items) {
return items.reduce((total, item) => total + (item.price * item.quantity), 0);
}
function calculateTax(amount) {
return amount * 0.1;
}
function calculateTotal(subtotal, tax) {
return subtotal + tax;
}
function processOrder(order) {
const subtotal = calculateSubtotal(order.items);
const tax = calculateTax(subtotal);
order.total = calculateTotal(subtotal, tax);
saveOrder(order);
notifyCustomer(order);
}
Meaningful Comments
เขียน Comment เมื่อจำเป็น อธิบายเหตุผลว่าทำไม ไม่ใช่อธิบายว่าทำอะไร
javascript
// Bad
// Loop through users
for (const user of users) {
// Check if admin
if (user.role === 'admin') {
// Do something
}
}
// Good
// Skip deleted users to prevent ghost data in reports
for (const user of activeUsers) {
if (user.role === 'admin') {
generateAdminReport(user);
}
}
Error Handling
จัดการ Error อย่างเหมาะสม ใช้ Try-Catch เมื่อจำเป็น
javascript
// Bad
function divide(a, b) {
return a / b;
}
// Good
function divide(a, b) {
if (b === 0) {
throw new Error('Division by zero is not allowed');
}
return a / b;
}
// Better
function divideNumbers(a, b) {
try {
return divide(a, b);
} catch (error) {
logger.error('Division failed:', error);
return null;
}
}
Consistent Formatting
ใช้รูปแบบการเขียนโค้ดที่สม่ำเสมอ ใช้ Code Formatter ช่วย
javascript
// Bad
function calculateTotal (items){
let total=0
for(const item of items){
total+=item.price*item.quantity
}
return total
}
// Good
function calculateTotal(items) {
let total = 0;
for (const item of items) {
total += item.price * item.quantity;
}
return total;
}
Avoid Magic Numbers
หลีกเลี่ยงการใช้ตัวเลขโดยตรงในโค้ด ให้กำหนดเป็นค่าคงที่ที่มีความหมาย
javascript
// Bad
if (user.age >= 18) {
allowAccess();
}
setTimeout(checkStatus, 86400000);
// Good
const LEGAL_AGE = 18;
const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000;
if (user.age >= LEGAL_AGE) {
allowAccess();
}
setTimeout(checkStatus, ONE_DAY_IN_MS);
Use Strong Types
ใช้ Type System ช่วยป้องกันข้อผิดพลาด
typescript
// Bad
function processUser(user) {
if (user.age > 18) {
// ...
}
}
// Good
interface User {
name: string;
age: number;
email: string;
}
function processUser(user: User) {
if (user.age > LEGAL_AGE) {
// ...
}
}
Dependency Injection
ส่งผ่านการพึ่งพาจากภายนอกเข้ามา แทนการสร้างภายในฟังก์ชัน
javascript
// Bad
class UserService {
constructor() {
this.database = new Database();
this.logger = new Logger();
}
}
// Good
class UserService {
constructor(database, logger) {
this.database = database;
this.logger = logger;
}
}
const database = new Database();
const logger = new Logger();
const userService = new UserService(database, logger);