VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
Kiến trúc và chất lượng codeCode sạch và refactor
Bài 9/17
5 phút

Code smell

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

Code chạy đúng chưa chắc đã dễ sửa. Có những dấu hiệu báo trước lần sửa sau sẽ vất vả: cùng một con số chép ở ba nơi, method dài hai trăm dòng. Nhận ra chúng sớm thì sửa rẻ hơn nhiều so với lúc chúng đã gây lỗi.

Khái niệm

👃 Code smell: dấu hiệu trong code cho thấy code khó hiểu, khó sửa, dù chưa chắc đã là lỗi.

Smell Dấu hiệu Cách sửa thường dùng
Trùng lặp cùng một công thức chép ở nhiều nơi tách thành một method
Method dài phải cuộn mới đọc hết một method tách thành nhiều method nhỏ có tên
Số trần (magic number) 110, 500000 nằm giữa code, không có tên đặt thành hằng có tên
Danh sách tham số dài method nhận năm, sáu tham số gom thành một class

Ví dụ

Tổng tiền có VAT 10% được tính ở hai nơi:

// Main.java
void main() {
    System.out.println(cartTotal(100000));
    System.out.println(invoiceTotal(100000));
}

long cartTotal(long subtotal) {
    return subtotal * 110 / 100;
}

long invoiceTotal(long subtotal) {
    return subtotal * 110 / 100;
}

Có hai smell cùng lúc: 110 là số trần, không cho biết nó là gì, và công thức bị trùng ở hai method. Sửa bằng một hằng và một method dùng chung:

// Main.java
static final int VAT_PERCENT = 10;

void main() {
    System.out.println(cartTotal(100000));
    System.out.println(invoiceTotal(100000));
}

long withVat(long subtotal) {
    return subtotal * (100 + VAT_PERCENT) / 100;
}

long cartTotal(long subtotal) {
    return withVat(subtotal);
}

long invoiceTotal(long subtotal) {
    return withVat(subtotal);
}
  • static final khai báo hằng số: gán một lần khi viết code, không đổi được lúc chạy. Tên hằng viết UPPER_SNAKE_CASE.
  • Tên VAT_PERCENT nói rõ con số là gì. VAT đổi thì sửa đúng một dòng.
  • Hai method gọi chung withVat, công thức chỉ còn một chỗ.

Thử ngay

Nhà nước giảm VAT còn 8%. Với bản chưa sửa, lập trình viên chỉ nhớ đổi cartTotal thành subtotal * 108 / 100, quên invoiceTotal. Chạy lại.

Đoán trước khi chạy: số tiền ở giỏ hàng và trên hoá đơn có khớp nhau không?

Xem kết quả
108000
110000

Không khớp: khách thấy 108.000 trong giỏ nhưng hoá đơn ghi 110.000. Công thức bị chép ở hai nơi thì sớm muộn sẽ có lúc sửa sót một nơi. Với bản đã sửa, chỉ cần đổi VAT_PERCENT là cả hai cùng đúng.

Lỗi hay gặp

Đặt hằng mà tên không nói gì. Tên như X vẫn không cho biết con số là gì, số trần chỉ đổi chỗ đứng.

// SAI — X là gì?
// Main.java
static final int X = 10;

void main() {
    System.out.println(100000 * X / 100);
}
// ĐÚNG — tên nói rõ ý nghĩa
// Main.java
static final int VAT_PERCENT = 10;

void main() {
    System.out.println(100000 * VAT_PERCENT / 100);
}

Tóm tắt

  • Code smell là dấu hiệu code khó sửa, chưa chắc là lỗi.
  • Bốn smell hay gặp: trùng lặp, method dài, số trần, tham số dài.
  • Số trần thay bằng hằng static final có tên. Công thức trùng gom về một method.
  • Tên hằng phải nói rõ con số là gì.

Tự kiểm tra

0/3 câu
Câu 1

if (total > 500000) xuất hiện ở năm file khác nhau. Smell nào, sửa thế nào?

Câu 2

Method createOrder(name, phone, email, street, city, district) có smell gì?

Câu 3

Khai báo static final int VAT_PERCENT = 10;. Có đổi được VAT_PERCENT lúc chương trình đang chạy không?

Đặt tên và method ngắnRefactor an toàn

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt