Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
"Code smell" (mùi code) là những dấu hiệu trong mã nguồn cho thấy có thể tồn tại vấn đề thiết kế sâu hơn, dù code vẫn chạy đúng. Chúng không phải lỗi, nhưng giống mùi khét trong bếp, bỏ qua lâu ngày sẽ thành chuyện lớn. Biết nhận ra các mùi phổ biến giúp bạn cải thiện code đúng chỗ, đúng lúc.
Hàm vài trăm dòng, phải cuộn nhiều màn hình mới đọc hết, là mùi code kinh điển. Chúng khó hiểu, khó test và nhiều lý do để thay đổi.
Cách xử lý: tách thành các hàm nhỏ có tên rõ ràng bằng Extract Function. Mỗi hàm một việc.
Cùng một đoạn logic được copy ở nhiều nơi. Sửa một chỗ mà quên chỗ khác là nguồn gốc của nhiều bug.
// Trùng lặpconst adminPrice = price - price * 0.1;const vipPrice = price - price * 0.2;// Gộp lạifunction applyDiscount(price, rate) {return price - price * rate;}const adminPrice = applyDiscount(price, 0.1);const vipPrice = applyDiscount(price, 0.2);Cách xử lý: rút phần chung thành hàm hoặc module dùng lại. Nhưng cẩn thận, chỉ gộp khi hai đoạn thực sự cùng ý nghĩa, không chỉ giống nhau về hình thức.
Hàm nhận 6-7 tham số khiến người gọi dễ nhầm thứ tự.
createUser("An", "an@mail.com", "0901", true, false, "VN");Cách xử lý: gom thành một đối tượng tham số có tên trường rõ ràng:
createUser({name: "An",email: "an@mail.com",phone: "0901",isActive: true,isAdmin: false,country: "VN"});Một class biết quá nhiều và làm quá nhiều: quản lý người dùng, gửi email, thanh toán, ghi log. Mọi thay đổi đều phải sửa vào class này.
Cách xử lý: chia theo trách nhiệm thành các class nhỏ (UserService, Mailer, PaymentService...) và để chúng phối hợp với nhau.
Những con số như 86400, 0.08, chuỗi như "st_3" rải rác trong code mà không ai biết ý nghĩa.
Cách xử lý: đặt thành hằng số có tên như SECONDS_PER_DAY, TAX_RATE, hoặc dùng enum cho các trạng thái.
Nhiều tầng if trong if trong for khiến mũi tên code trôi về bên phải.
Cách xử lý: dùng guard clause (thoát sớm), tách điều kiện thành hàm có tên như isEligibleForDiscount(user), hoặc dùng bảng tra cứu thay cho chuỗi if/else dài.
Khi bạn phải viết comment dài để giải thích một đoạn code rối, thường vấn đề nằm ở code chứ không ở việc thiếu comment.
Cách xử lý: đổi tên, tách hàm để code tự giải thích; giữ comment cho phần "vì sao" (lý do, ràng buộc nghiệp vụ), không cho phần "cái gì".
Một hàm liên tục truy cập dữ liệu của đối tượng khác thay vì của chính nó, ví dụ order.customer.address.city được gọi chằng chịt khắp nơi.
Cách xử lý: chuyển hàm về class chứa dữ liệu, hoặc thêm một phương thức rõ nghĩa ở class đó, như order.getShippingCity().
Hàm không ai gọi, biến không dùng, khối code bị comment lại từ lâu. Chúng gây nhiễu và làm người đọc phân vân.
Cách xử lý: xóa đi. Nếu cần, lịch sử Git vẫn giữ lại để khôi phục.
Mỗi lần thêm một loại thanh toán mới, bạn lại phải sửa năm file khác nhau. Đó là dấu hiệu thiết kế đang bị phân mảnh (Shotgun Surgery).
Cách xử lý: gom các phần cùng lý do thay đổi lại với nhau, hoặc dùng đa hình/chiến lược (strategy) để thêm loại mới chỉ bằng một class.
| Mùi code | Dấu hiệu | Hướng xử lý |
|---|---|---|
| Hàm dài | Phải cuộn nhiều | Extract Function |
| Trùng lặp | Copy-paste | Rút thành hàm chung |
| Nhiều tham số | Hơn 4 tham số | Đối tượng tham số |
| God Class | Class làm đủ thứ | Chia theo trách nhiệm |
| Magic value | Số, chuỗi vô nghĩa | Hằng số, enum |
| If lồng sâu | Code trôi sang phải | Guard clause |
| Dead code | Không dùng | Xóa |
Những mùi này là gợi ý chứ không phải luật. Một hàm dài 40 dòng mà rất dễ đọc vẫn tốt hơn năm hàm nhỏ nhưng rối rắm. Hãy dùng chúng như bộ giác quan: khi ngửi thấy, dừng lại và tự hỏi liệu thay đổi có làm code dễ hiểu và dễ sửa hơn hay không. Ưu tiên xử lý những mùi nằm ở vùng code bạn hay phải sửa, vì đó là nơi lợi ích lớn nhất.
Rèn thói quen nhận ra code smell sẽ nâng chất lượng code của bạn nhanh chóng, cả khi viết lẫn khi review code của người khác. Mỗi lần mở file, hãy thử tìm một mùi và xử lý bằng một bước refactor nhỏ.
Nếu bạn muốn học cách thiết kế code tốt qua dự án thật, có thể tham khảo danh sách khóa học trên codebem.com.
Nguyễn Đình Cường
0 comment