Code smell thường gặp: nhận biết sớm và cách xử lý

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

"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.

1. Hàm quá dài

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.

2. Code trùng lặp

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.

3. Danh sách tham số dài

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"});

4. Class "thần thánh" (God Class)

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.

5. Số và chuỗi "ma thuật" (Magic values)

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.

6. Điều kiện lồng nhau sâu

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.

7. Comment che đậy code tồ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ì".

8. Feature Envy (hàm "ghen tị" với class khác)

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().

9. Code chết (Dead code)

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.

10. Thay đổi một nơi kéo theo sửa nhiều nơi

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.

Bảng tóm tắt nhanh

Mùi codeDấu hiệuHướng xử lý
Hàm dàiPhải cuộn nhiềuExtract Function
Trùng lặpCopy-pasteRút thành hàm chung
Nhiều tham sốHơn 4 tham sốĐối tượng tham số
God ClassClass làm đủ thứChia theo trách nhiệm
Magic valueSố, chuỗi vô nghĩaHằng số, enum
If lồng sâuCode trôi sang phảiGuard clause
Dead codeKhông dùngXóa

Đừng xem mùi code là luật sắt

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.

Kết luận

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.

author_photo
Nguyễn Đình Cường

0 comment