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

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

Chia sẻ kiến thức 20/03/2022

Viết clean code không phải là việc dễ dàng và cần thời gian để luyện tập, clean code tuy mất thời gian hơn nhưng sẽ giúp chúng ta tiết kiệm thời gian để đọc code sau này, giúp việc cải tiến và mở rộng các dự án trở nên nhanh chóng, dễ dàng hơn. Trong bài viết này sẽ thảo luận về một số quy ước cần tuân thủ để viết clean code.

Lợi ích của việc tuân theo các quy ước

  • Code “sạch” hơn (clean code), không bị lỗi
  • Code chất lượng hơn
  • Code sẽ dễ đọc hơn
  • Bảo trì code sẽ 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. Magic numbers

Magic number có nghĩa là đang gán một con số 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ể, và không gán giá trị đó cho một biến có ý nghĩa. Vấn đề xảy ra là sau đó có người lên tiếng với code của bạn, họ không biết được ý nghĩa của giá trị trực tiếp đó.

// Bad practice
for (let i = 0; i < 60; i++) {
  // do something
}

// Good practice
const MINUTES_OF_THE_HOUR = 60;
for (let i = 0; i < MINUTES_OF_THE_HOUR; i++) {
  // do something
}

2. Tránh dùng quá nhiều vòng lặp lồng nhau

Đôi khi việc bạn 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 là tách tất cả các vòng lặp ra thành function riêng biệt. Giả sử bạn có một mảng (array) chứa một mảng (firstArr), mảng firstArr này lại chứa mảng khác (secondArr), và bạn muốn lấy ra phần tử của mảng trong cùng (secondArr). Để xử lý yêu cầu này, thông thường bạn hay viết các vòng lặp lồng nhau, nhưng đây không phải là cách hay. Bạn hoàn toàn có thể viết một function để giải quyết vấn đề, và function này gọn gàng hơn, ít lặp code hơn, dễ đọc và có thể tái sử dụng.

// Bad practice
const array = [[["hello world"]]];

array.forEach((firstArr) => {
  firstArr.forEach((secondArr) => {
    secondArr.forEach((element) => {
      console.log(element);
    });
  });
});

// Good practice
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 các comments

Comments giúp lập trình viên khác làm việc trong cùng một dự án sau này hiểu code nhanh hơn, dễ dàng hơn. Tuy nhiên, nếu code cần đến comments thì có thể do bản thân coder chưa đủ rõ ràng, dễ hiểu. Dưới đây là 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 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 bản thân 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 (lớp) quá dài bạn nên tách thành nhiều phần. Điều này sẽ làm cho code của bạn clean 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.

// Bad practice
const addSub = (a, b) => {
  // add
  const addition = a + b;

  // sub
  const sub = a - b;

  // returning as a string
  return `${addition}${sub}`;
};

// Good practice
// add
const add = (a, b) => {
  return a + b;
};

// sub
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 trong code của bạn nhiều hơn một lần. Điều này nghĩa là phần code đó của bạn nên được viết thành một function.

Lấy từ 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ự nhau ba lần và cách tối ưu hơn là viết một function có chức năng tương đương, và function đó có thể tái sử dụng.

// Bad practice
const array = [[["hello world"]]];

array.forEach((firstArr) => {
  firstArr.forEach((secondArr) => {
    secondArr.forEach((element) => {
      console.log(element);
    });
  });
});

// Good practice
const array = [[["hello world"]]];

const getValuesOfNestedArray = (element) => {
  if (Array.isArray(element)) {
    return getValuesOfNestedArray(element[0]);
  }

  return element;
};

getValuesOfNestedArray(array);

Xét thêm một vài ví dụ khác:

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

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

6. Đặt tên các biến theo chuẩn Camel Case

Camel Case

Camel Case là quy tắc đặt tên cho cả 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.

let camelCase = "hello";
const thisIsCamelCase = () => {
  // do something
};

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

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

Nếu bạn cần function lấy thông tin ngân hàng của người dùng, thì không nên sử dụng tên như getUserInfo hoặc kiểu tên tương tự. Ngược lại, nên sử dụng tên getUserBankInfo sẽ 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 hơn là ngắn gọn

Nếu có thể, bạn nên đặt tên thật ngắn gọn. Tuy nhiên trong trường hợp bạn không chắc chắn về cách đặ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 hai, ba từ để đặt tên, thì tốt hơn hết là nên ưu tiên mô tả chi tiết.

Giả sử chúng ta 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ọ. Chúng ta phải chọn tên chi tiết, có ý nghĩa và thể hiện được mục đích của function ngắn gọn.

// Bad practice
const findUser

// Good practice
// descriptive version
const findUserByPhoneOrEmail

// shorter version
const getUserFromDatabase

9. Sử dụng các động từ nhất quán cho các khái niệm

Function thường được sử dụng để thực hiện các hành động, ví dụ như đọc, xóa, tạo mới, chỉnh sửa gì đó. 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, chúng ta có thể đặt tên chứa động từ createreadupdate hoặc delete.

Nếu cần lấy thông tin người dùng từ cơ sở dữ liệu, thì không nên đặt tên function là userInfouser,… Chúng ta nên sử dụng tên getUserInfo.

// Bad practice
function userInfo() {
  // do something
}

// Good practice
function getUserInfo() {
  // do something
}

Giả sử bạn muốn viết các function tìm email, số điện thoại của người dùng, bạn không nên đặt tên function là getUserEmailretrieveUserPhone (thực hiện cùng một hành động nhưng sử dụng động từ không nhất quán). Hãy đặt tên là getUserEmailgetUserPhone (sử dụng 1 động từ get nhất quán).

// Bad practice
function getUserEmail() {
  // do something
}
function retrieveUserPhone() {
  // do something
}

// Good practice
function getUserEmail() {
  // do something
}
function getUserPhone() {
  // do something
}

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ó phải màu xanh không, có túi khí không: sedansoldgreenairbag.

// Bad practice
let car = {};
car.sedan, car.sold, car.green, car.airbag;

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

Viết như vậy sẽ cụ thể hơn rất nhiều, 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:

  • https://www.pluralsight.com/blog/software-development/10-steps-to-clean-code
  • https://toihocdesignpattern.com/chuong-1-code-sach.html

>>> 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 FUNiX ngay tại đây:

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

7+ bước giúp bạn học lập trình viết code tốt hơn
Học lập trình tại FUNiX không chỉ giúp bạn giỏi code
Những website luyện thuật toán lập trình giúp bạn học code hiệu quả

 

Lương Thuận

ĐĂNG KÝ TƯ VẤN HỌC LẬP TRÌNH TẠI FUNiX

Bình luận (
0
)

Bài liên quan

  • Tầng 0, tòa nhà FPT, 17 Duy Tân, Q. Cầu Giấy, Hà Nội
  • info@funix.edu.vn
  • 0782313602 (Zalo, Viber)        
Chat Button
Chat với FUNiX GPT ×

yêu cầu gọi lại