Chapter
Clean Code adalah kode yang mudah dibaca, dipahami, dan dimodifikasi oleh developer lain (termasuk kamu sendiri 6 bulan ke depan).
// ❌ Tidak jelas
const d = new Date()
const arr = users.filter(u => u.a > 18)
function calc(x, y) { return x * y * 0.1 }
// ✅ Jelas dan deskriptif
const currentDate = new Date()
const adultUsers = users.filter(user => user.age > 18)
function calculateTax(price, quantity) { return price * quantity * 0.1 }// ❌ Fungsi terlalu besar, banyak tujuan
async function handleUser(req, res) {
const { email, password, nama } = req.body
if (!email || !password || !nama) return res.status(400).json({ error: '...' })
const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/
if (!emailRegex.test(email)) return res.status(400).json({ error: '...' })
const existing = await User.findOne({ email })
if (existing) return res.status(409).json({ error: '...' })
const hashed = await bcrypt.hash(password, 12)
const user = await User.create({ nama, email, password: hashed })
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET)
res.json({ user, token })
}
// ✅ Dipecah jadi fungsi kecil
function validateRegisterInput(data) {
const { email, password, nama } = data
if (!email || !password || !nama) throw new Error('Semua field wajib diisi')
if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(email)) throw new Error('Email tidak valid')
if (password.length < 6) throw new Error('Password minimal 6 karakter')
}
async function checkEmailUnique(email) {
const existing = await User.findOne({ email })
if (existing) throw new Error('Email sudah terdaftar')
}
async function createUserWithToken(userData) {
const hashed = await bcrypt.hash(userData.password, 12)
const user = await User.create({ ...userData, password: hashed })
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET)
return { user, token }
}
async function handleRegister(req, res) {
try {
validateRegisterInput(req.body)
await checkEmailUnique(req.body.email)
const result = await createUserWithToken(req.body)
res.status(201).json(result)
} catch (error) {
res.status(400).json({ error: error.message })
}
}S — Single Responsibility
Satu class/fungsi, satu tanggung jawab.
O — Open/Closed
Terbuka untuk extension, tertutup untuk modifikasi.
D — Don't Repeat Yourself (DRY)
// ❌ Duplikasi kode
function validateEmail(email) {
return /^[^s@]+@[^s@]+.[^s@]+$/.test(email)
}
// ... di tempat lain
if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(userEmail)) { ... }
// ✅ Tulis sekali, pakai berulang
const isValidEmail = (email) => /^[^s@]+@[^s@]+.[^s@]+$/.test(email)