10 nguyên tắc cần thiết để viết “clean code”

0
33
Rate this post

Viết “clean code” không hề dễ dàng và đòi hỏi sự luyện tập, nhưng nó đáng làm vì sẽ tiết kiệm thời gian cho việc đọc code trong tương lai và giúp cải tiến và mở rộng dự án dễ dàng hơn. Trong bài viết này, chúng ta sẽ thảo luận về những quy tắc cần tuân thủ để viết “clean code” một cách hiệu quả.

Lợi ích của việc tuân thủ các quy tắc

  • Code sẽ trở nên “sạch” hơn, không có lỗi
  • Code có chất lượng cao hơn
  • Code dễ đọc hơn
  • Việc bảo trì code trở nên dễ dàng hơn

“Clean code đơn giản và trực tiếp, cũng giống như một bài văn xuôi được viết mạch lạc. Clean code không làm cho ý tưởng của lập trình viên trở nên phức tạp mà thay vào đó là những dòng lệnh cụ thể, làm cho những nội dung trừu tượng trở nên rõ ràng, dễ hiểu hơn.” — Robert C. Martin

1. Số phép thuật kỳ diệu

Magic numbers
Magic number là cách gán giá trị mà không có ý nghĩa rõ ràng. Đôi khi bạn sử dụng một giá trị cho một mục đích cụ thể, nhưng không gán giá trị đó cho một biến có ý nghĩa. Vấn đề xảy ra sau này khi có ai đó đọc code của bạn và không hiểu ý nghĩa của giá trị đó trực tiếp.

Cách viết không tốt


// Bad practice
for (let i = 0; i < 60; i++) {
// làm gì đó
}

// Cách viết tốt
const MINUTES_OF_THE_HOUR = 60;
for (let i = 0; i < MINUTES_OF_THE_HOUR; i++) {
// làm gì đó
}


## 2. Tránh sử dụng quá nhiều vòng lặp lồng nhau
Đôi khi việc sử dụng nhiều vòng lặp lồng nhau làm code trở nên rất khó hiểu. Giải pháp tốt là tách tất cả các vòng lặp thành các function riêng biệt. Ví dụ, nếu bạn có một mảng chứa mảng, và bạn muốn lấy ra phần tử của mảng trong mảng đó, hãy viết một function để giải quyết vấn đề. Function này sẽ gọn gàng hơn, ít lặp code hơn, dễ đọc và có thể tái sử dụng.

> Cách viết không tốt
```javascript
// Bad practice
const array = [[["hello world"]]];
array.forEach((firstArr) => {
  firstArr.forEach((secondArr) => {
    secondArr.forEach((element) => {
      console.log(element);
    });
  });
});

// Cách viết tốt
const array = [[["hello world"]]];
const getValuesOfNestedArray = (element) => {
  if (Array.isArray(element)) {
    return getValuesOfNestedArray(element[0]);
  }
  return element;
};
getValuesOfNestedArray(array);

3. Không phụ thuộc vào comments

Comments giúp lập trình viên khác hiểu code nhanh hơn, dễ dàng hơn khi làm việc trên cùng một dự án trong tương lai. Tuy nhiên, nếu code của bạn cần comments thì có thể bạn chưa viết code đủ rõ ràng và dễ hiểu. Dưới đây là một câu nói nổi tiếng về việc viết comments của Jeff Atwood:

“Comments vốn dĩ không phải là xấu, nhưng cũng không hẳn là tốt, đôi khi người viết code bị phụ thuộc vào comments. Bản thân bạn luôn tự ý thức viết code của mình như thể không có comments. Chính vì vậy, hãy viết code đơn giản nhất, dễ hiểu nhất, rõ ràng nhất có thể.” — Jeff Atwood

Nhìn chung, comments là tốt, nhưng chính code cần phải dễ hiểu, dễ giải thích kể cả khi không có comment.

Xem thêm tại: Bí quyết để bạn vượt trội trong nghề lập trình viên

4. Tránh viết các function quá dài

Khi một function hoặc một class quá dài, bạn nên tách thành các phần nhỏ hơn. Điều này làm cho code sạch hơn, dễ hiểu hơn và có thể tái sử dụng.

Giả sử chúng ta cần cộng và trừ hai số. Thông thường bạn có thể dùng một function duy nhất, nhưng cách tốt nhất là nên chia thành hai function khác nhau. Khi viết các function riêng lẻ, bạn có thể tái sử dụng chúng trong toàn bộ ứng dụng.

Cách viết không tốt


// Bad practice
const addSub = (a, b) => {
// Cộng
const addition = a + b;
// Trừ
const sub = a - b;
// Trả về dưới dạng chuỗi
return `${addition}${sub}`;
};

// Cách viết tốt
// Cộng
const add = (a, b) => {
return a + b;
};
// Trừ
const sub = (a, b) => {
return a – b;
};


## 5. Tránh việc lặp code
Lặp code nghĩa là một khối code được sử dụng nhiều hơn một lần trong code của bạn. Điều này nghĩa là phần code đó nên được viết thành một function riêng.

Dựa vào ví dụ ở trên (Mục 2: Tránh dùng nhiều vòng lặp lồng vào nhau). Nhìn vào phần Bad practice: Bạn đã lặp lại khối code tương tự ba lần, trong khi cách tối ưu hơn là viết một function tương đương và có thể tái sử dụng.

> Cách viết không tốt
```javascript
// Bad practice
const array = [[["hello world"]]];
array.forEach((firstArr) => {
  firstArr.forEach((secondArr) => {
    secondArr.forEach((element) => {
      console.log(element);
    });
  });
});

// Cách viết tốt
const array = [[["hello world"]]];
const getValuesOfNestedArray = (element) => {
  if (Array.isArray(element)) {
    return getValuesOfNestedArray(element[0]);
  }
  return element;
};
getValuesOfNestedArray(array);

Thêm một vài ví dụ khác:

Cách viết không tốt


// Bad practice
const getUserCredentials = (user) => {
const name = user.name;
const surname = user.surname;
const password = user.password;
const email = user.email;
};

// Cách viết tốt
const getUserCredentials = (user) => {
const { name, surname, password, email } = user;
};


## 6. Đặt tên các biến theo chuẩn Camel Case
![Camel Case](https://funix.edu.vn/wp-content/uploads/2022/03/Camel-Case.jpeg)
Camel Case là quy tắc đặt tên cho biến, function và các định danh khác. Theo quy tắc Camel Case, tên phải bắt đầu bằng chữ cái viết thường và tất cả các chữ cái đầu tiên của những từ tiếp theo sẽ được viết hoa.

```javascript
let camelCase = "hello";

const thisIsCamelCase = () => {
  // làm gì đó
};

7. Đặt tên ý nghĩa

Đặt tên có ý nghĩa là quy tắc quan trọng nhất. Luôn sử dụng tên có ý nghĩa cho biến, function và các tên khác. Hãy chọn tên thể hiện ý nghĩa cho mục đích của bạn.

Ví dụ, nếu bạn cần một function lấy thông tin ngân hàng của người dùng, hãy tránh sử dụng tên như getUserInfo hoặc tương tự. Thay vào đó, hãy sử dụng tên getUserBankInfo để làm cho chức năng của function cụ thể hơn.

Đọc ngay: Học lập trình online có ưu điểm vượt trội gì?

8. Ưu tiên các mô tả chi tiết

Nếu có thể, hãy đặt tên ngắn gọn. Tuy nhiên, trong trường hợp bạn không chắc chắn về việc đặt tên ngắn gọn có thể hiện đủ ý nghĩa hay không, và thấy khó khăn trong việc tìm ra cụm từ ngắn gọn, thì tốt hơn hết là nên ưu tiên mô tả chi tiết.

Ví dụ, bạn cần đặt tên cho một function để tìm người dùng thông qua số điện thoại hoặc email của họ. Bạn phải chọn tên cụ thể, có ý nghĩa và thể hiện được mục đích của function một cách ngắn gọn.

Cách viết không tốt


// Bad practice
const findUser;

// Cách viết tốt
// Phiên bản mô tả chi tiết
const findUserByPhoneOrEmail;
// Phiên bản rút gọn
const getUserFromDatabase;


## 9. Sử dụng các động từ nhất quán
Function thường được sử dụng để thực hiện các hành động như đọc, xóa, tạo mới hoặc chỉnh sửa. Vì vậy, tên function nên là một cụm động từ và chắc chắn rằng bạn sử dụng một động từ nhất quán cho cùng một hành động.

Nếu bạn cần một function CRUD, hãy đặt tên chứa động từ `create`, `read`, `update` hoặc `delete`.

Nếu bạn cần lấy thông tin người dùng từ cơ sở dữ liệu, hãy tránh đặt tên function là `userInfo`, `user`, và hãy sử dụng tên `getUserInfo` thay vào đó.

> Cách viết không tốt
```javascript
// Bad practice
function userInfo() {
  // làm gì đó
}

// Cách viết tốt
function getUserInfo() {
  // làm gì đó
}

Ví dụ khác:

Cách viết không tốt


// Bad practice
function getUserEmail() {
// làm gì đó
}

function retrieveUserPhone() {
// làm gì đó
}

// Cách viết tốt
function getUserEmail() {
// làm gì đó
}

function getUserPhone() {
// làm gì đó
}


## 10. Đặt tên biến Boolean cụ thể trong câu lệnh if-then
Giả sử, bạn muốn kiểm tra các đặc điểm của một chiếc ô tô xem có phải là sedan hay không, đã được bán ra chưa, có màu xanh không, có túi khí không: `sedan`, `sold`, `green`, `airbag`.

> Cách viết không tốt
```javascript
let car = {};
car.sedan, car.sold, car.green, car.airbag;

Cách viết tốt

let car = {};
car.isSedan, car.isSold, car.isGreen, car.hasAirbag;

Viết như vậy sẽ cụ thể hơn, tự nhiên hơn và làm cho chương trình dễ giải mã hơn.

Tài liệu tham khảo:

Nếu bạn đang có nhu cầu tìm hiểu về khóa học lập trình đi làm ngay, hãy liên hệ với Dnulib ngay để biết thêm thông tin chi tiết.

Xem thêm chuỗi bài viết liên quan:

Lương Thuận

Đọc thêm