CodeGym /Các khóa học /JAVA 25 SELF /Phong cách và tính dễ đọc của mã, code conventions

Phong cách và tính dễ đọc của mã, code conventions

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Giới thiệu

Trong lập trình, phong cách không phải là chuyện thời trang mà là chuyện sống còn. Java là ngôn ngữ mà các đội rất lớn sử dụng, và nếu mỗi người viết “như đã quen”, dự án sẽ nhanh chóng biến thành một mớ các mảnh rời rạc mà chỉ tác giả mới hiểu được (và đôi khi còn không).

Phong cách mã là tập hợp các quy tắc giúp mã có thể đọc theo cách giống nhau đối với mọi người. Nó giống như biển báo giao thông: nếu bỏ qua, lưu thông sẽ nhanh chóng rơi vào hỗn loạn.

Tại sao điều này quan trọng?

  • Tính dễ đọc: mã được đọc thường xuyên hơn là được viết. Phong cách tệ giống như chữ bác sĩ xấu: không ai hiểu nó viết gì.
  • Khả năng bảo trì: nếu mã được viết theo quy tắc, việc sửa đổi sẽ dễ hơn, giảm khả năng vô tình làm hỏng thứ gì đó.
  • Làm việc nhóm: trong một đội, mọi người nên hiểu nhau mà không cần nhiều câu hỏi thừa.
  • Công cụ: auto-formatter và các trình phân tích mã hoạt động tốt hơn khi phong cách thống nhất.

2. Những lỗi phong cách mã phổ biến (và cách tránh)

Không tuân thủ thụt lề và ngoặc

Lỗi:
Mã không có thụt lề và ngoặc lộn xộn gây khó chịu cho mắt và não.

if(x>0){
System.out.println("x là số dương");
}else{
System.out.println("x không phải số dương");
}

Cách đúng:

if (x > 0) {
    System.out.println("x là số dương");
} else {
    System.out.println("x không phải số dương");
}

Bình luận:
Hãy dùng bốn dấu cách cho mỗi mức lồng nhau (đây là chuẩn của Java). Tab là không nên dùng, trừ khi cả đội đã thống nhất khác.

Tên biến, phương thức và lớp không phù hợp

Lỗi:

int a = 5;
String s = "Vasya";
void f() { /* ... */ }

Cách đúng:

int age = 5;
String userName = "Vasya";
void printReport() { /* ... */ }

Bình luận:
Tên phải có ý nghĩa và phản ánh bản chất của biến hoặc phương thức.

  • Lớp — viết hoa chữ cái đầu, CamelCase: UserAccount.
  • Phương thức và biến — chữ cái đầu viết thường, camelCase: calculateSalary, userList.

Các phương thức và lớp quá dài

Lỗi:
Phương thức 100 dòng, lớp 1000 dòng — chế độ ác mộng thực sự cho việc bảo trì.

Cách đúng:
Mỗi phương thức nên làm một việc và ngắn gọn (lý tưởng — vừa một màn hình). Các lớp cũng không nên phình to như “Chiến tranh và Hòa bình”.

Ví dụ:

Xấu:

public void processOrder() {
    // 200 dòng mã
}

Tốt:

public void processOrder() {
    validateOrder();
    calculateTotal();
    saveToDatabase();
    sendEmailConfirmation();
}

Sử dụng “con số” và chuỗi “ma thuật”

Lỗi:

if (status == 42) {
    // ...
}

Cách đúng:

public static final int STATUS_APPROVED = 42;

if (status == STATUS_APPROVED) {
    // ...
}

Bình luận:
Thay vì các con số và chuỗi “ma thuật”, hãy dùng hằng số (static final). Trong các phiên bản Java mới còn có enum — dùng chúng cho các tập giá trị hữu hạn.

Chú thích: thiếu hoặc thừa

Lỗi 1:
Không có chú thích nào — khó hiểu đoạn mã phức tạp làm gì.

Lỗi 2:
Chú thích cho mọi hành động, kể cả điều hiển nhiên.

// Tăng x thêm 1
x = x + 1;

// Kiểm tra x có bằng 10 không
if (x == 10) {
    // ...
}

Những chú thích như vậy chỉ gây vướng víu! Chỉ chú thích các điểm phức tạp hoặc không hiển nhiên. Nói chung, mã tốt nên dễ hiểu mà không cần chú thích — chú thích dùng để giải thích “tại sao”, không phải “làm gì”.

// Tính đến chiết khấu cho khách VIP
double total = calculateTotalWithDiscount();

3. Quy ước Java: cách các chuyên gia viết

Trong Java có các tiêu chuẩn định dạng chính thức và de facto. Oracle Java Code ConventionsGoogle Java Style Guide là phổ biến nhất.

Thụt lề và ngoặc

Dấu ngoặc nhọn mở được đặt trên cùng dòng với khai báo:

public void print() {
    // ...
}

Mức lồng nhau — bốn dấu cách.

Đặt tên

  • Lớp và interface: CamelCase bắt đầu bằng chữ hoa (Person, UserAccount).
  • Phương thức và biến: camelCase bắt đầu bằng chữ thường (calculateSalary, userList).
  • Hằng số: VIẾT_HOA_TOÀN_BỘ_KÈM_GẠCH_DƯỚI (MAX_SIZE, DEFAULT_TIMEOUT).
  • Gói (package): chỉ chữ thường, có thể có dấu chấm (com.example.project).

Khoảng trắng

Khoảng trắng quanh toán tử và sau dấu phẩy:

int sum = a + b;
System.out.println(name, age);

Không đặt khoảng trắng sau dấu mở và trước dấu đóng ngoặc:

if (x > 0) { ... }

Độ dài dòng

Khuyến nghị không vượt quá 100–120 ký tự mỗi dòng. (Vâng, màn hình của bạn rất lớn, nhưng mã vẫn dễ đọc hơn khi nó không chạy dài quá ngang màn hình.)

Thứ tự khai báo các thành viên của lớp

Thứ tự khuyến nghị (theo Oracle):

  1. Các trường (trước là static, sau đó là thường)
  2. Constructor
  3. Các phương thức

Ví dụ:

public class User {
    private static int userCount;
    private String name;

    public User(String name) {
        this.name = name;
        userCount++;
    }

    public String getName() {
        return name;
    }
}

4. Ví dụ: refactoring phong cách kém

Đây là một ví dụ về lớp bạn có thể gặp ngoài đời thực:

class person{String n;int a;void p(){System.out.println(n+" "+a);}}

Ở đâu đó trong văn phòng, có một lập trình viên Java đang khóc vì đoạn mã này.

Hãy cải thiện nó:

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void print() {
        System.out.println(name + " " + age);
    }
}

Đã thay đổi gì:

  • Lớp và các thành viên có modifier truy cập đúng.
  • Tên có ý nghĩa, dễ đọc.
  • Mỗi thành viên lớp trên một dòng mới.
  • Dùng constructor để khởi tạo.
  • Các trường private để đảm bảo tính đóng gói.

5. Những lưu ý hữu ích

Auto-formatter

Các IDE hiện đại (IntelliJ IDEA, Eclipse, VS Code) có thể tự động định dạng mã theo chuẩn.

Phím tắt:

  • IntelliJ IDEA: Ctrl + Alt + L
  • Eclipse: Ctrl + Shift + F

Phân tích tĩnh

Các công cụ như Checkstyle, SonarLint, PMD giúp phát hiện vi phạm phong cách và lỗi tiềm ẩn trước cả khi chạy chương trình.

Trông như thế nào:

  • Checkstyle sẽ cảnh báo nếu bạn đặt tên biến là x thay vì userAge.
  • SonarLint sẽ nhắc nếu phương thức quá dài hoặc lớp vi phạm các nguyên tắc SOLID.

Phân tách trách nhiệm và “mã sạch”

  • Mỗi lớp nên chỉ chịu trách nhiệm về một nhiệm vụ (Single Responsibility Principle).
  • Đừng ngại tạo thêm lớp và phương thức — đó không phải “phình to” mà là sự quan tâm tới người đọc trong tương lai.
  • Cố gắng tránh lặp mã: nếu thấy hai đoạn giống nhau — hãy tách chúng thành một phương thức riêng.

Hằng số và “con số ma thuật”: cách làm đúng

Thay vì:

double price = 100 * 0.18;

Tốt hơn:

public static final double VAT_RATE = 0.18;
double price = 100 * VAT_RATE;

Nếu bạn thường gặp các tập giá trị cố định — hãy dùng enum:

public enum Status {
    NEW, IN_PROGRESS, DONE
}

6. Những lỗi điển hình về phong cách và tính dễ đọc của mã

Lỗi số 1: Bỏ qua code conventions.
Nếu trong đội không có phong cách thống nhất, mã sẽ nhanh chóng trở nên khó đọc và khó bảo trì. Ngay cả khi bạn viết một mình, một năm sau bạn sẽ tự cảm ơn mình.

Lỗi số 2: Tên quá ngắn/quá dài.
Biến a hoặc temp — không tốt. Biến theCurrentUserNameThatIsUsedForAuthorizationInTheSystem — cũng không nên. Hãy tìm sự cân bằng: userName, age, bookList.

Lỗi số 3: “Con số ma thuật”.
Chèn số và chuỗi trực tiếp vào mã gây khó bảo trì và tăng khả năng lỗi.

Lỗi số 4: Phương thức và lớp khổng lồ.
Phương thức càng lớn — càng khó kiểm thử và hiểu. Hãy chia thành các phần logic.

Lỗi số 5: Cấu trúc lớp kém.
Các trường rải rác khắp nơi, phương thức được khai báo theo thứ tự ngẫu nhiên — tất cả khiến bạn khó tìm đúng chỗ cần.

Lỗi số 6: Chú thích thừa hoặc thiếu.
Chú thích “khởi tạo biến” cạnh int x = 0; là không cần. Chú thích giải thích logic nghiệp vụ phức tạp — rất cần.

Lỗi số 7: Định dạng không nhất quán.
Một phần dự án — bốn dấu cách, phần khác — Tab; chỗ này ngoặc ở dòng mới, chỗ kia ngoặc cùng dòng. Điều này trông luộm thuộm và gây khó chịu cho đồng nghiệp.

1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
OOP — lỗi phổ biến
OOP — lỗi phổ biến
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION