Kinh nghiệm để viết Clean Code trong JavaScript

Anh em lập trình viên chắc không xa lạ với khái niệm Clean Code trong lập trình, mặc dù vậy để viết được code một cách clean quả thực là một thách thức, nhất là đối với ngôn ngữ lập trình JavaScript. Bài viết hôm nay, mình cùng các bạn chia sẻ một số kinh nghiệm để thực hành viết Clean Code trong JS, và hãy thử xem các bạn đã áp dụng được bao nhiêu trong số những điều dưới đây nhé.

Clean Code là gì?

Clean Code – “Mã Sạch” là cách viết code đơn giản và dễ hiểu, dễ bảo trì, có khả năng mở rộng source code mà vẫn có thể đáp ứng được các yêu cầu về mặt tính năng, hiệu năng hay bảo mật. Khái niệm tuy đơn giản nhưng để một source code đáp ứng được tiêu chuẩn Clean Code lại là một vấn đề không dễ để giải quyết. Clean Code còn thể hiện kinh nghiệm, đồng thời ở một khía cạnh nào đó sẽ đánh giá trình độ của lập trình viên.

Clean-Code-trong-JavaScript-1

Mỗi ngôn ngữ lập trình đều có những tiêu chuẩn khi viết code, cùng các thủ thuật, lời khuyên từ kinh nghiệm của những lập trình viên đi trước giúp bạn áp dụng vào dự án của mình để có thể thực hành clean code. Mặc dù vậy, để áp dụng đúng và chuẩn thì luôn cần có những trải nghiệm thực tế cùng việc thực hành một cách tích cực.

Viết Clean Code trong JavaScript

JavaScript vốn dĩ là một ngôn ngữ lập trình động với các ràng buộc lỏng lẻo trong quy tắc viết code; vì thế lập trình viên JS thường dễ tạo ra những đoạn code rối, tiềm ẩn nguy cơ gặp lỗi hoặc chỉ đơn giản là rất khó để đọc, hiểu hay bảo trì về sau. Để khắc phục được điều này và giúp cải thiện chất lượng source code dự án thì việc áp dụng Clean Code cho JS là điều vô cùng cần thiết.

Chúng ta cùng nhau tìm hiểu một số kinh nghiệm để giúp viết Clean Code trong JavaScript dưới đây nhé.

1. Cách đặt tên biến

Nhiều bạn ngại đặt tên biến dài, thích đặt tên biến ngắn cho “tiện”; điều này vô tình khiến người khác hay chính bạn sau một thời gian đọc lại không hiểu mục đích biến đấy được tạo ra và sử dụng để làm gì. Lời khuyên cho bạn khi đặt tên biến là hãy sử dụng tên thể hiện ý định, mục đích sử dụng biến đó; không ngại việc đặt tên dài và tốt hơn nữa là có thể dễ gợi ý tìm kiếm sau này. Ví dụ:

// DON'T
let d
let elapsed
const ages = arr.map((i) => i.age)

// DO
let daysSinceModification
const agesOfUsers = users.map((user) => user.age)

Bạn cũng không nên đặt thừa chỉ để dành cho việc mô tả loại dữ liệu hay một số tiền tố/ hậu tố đi kèm như trong văn viết như ví dụ dưới đây:

// DON'T
let nameString
let theUsers

// DO
let name
let users

Đừng cố gắng viết tắt tên biến, vì đoạn code của bạn sẽ có nhiều người khác trong team cần đọc. Hãy cố gắng viết code sao cho một người đọc code của bạn như đang đọc một đoạn văn có đầy ý nghĩa dễ hiểu mà không cần phải giải thích.

// DON'T
let fName, lName
let cntr
let full = false
if (cart.size > 100) {
  full = true
}

// DO
let firstName, lastName
let counter
const MAX_CART_SIZE = 100
// ...
const isFull = cart.size > MAX_CART_SIZE

2. Cách viết tên hàm

Robert Cecil Martin – tác giả của cuốn Clean Code đưa ra lời khuyên khi viết hàm rằng: Mỗi hàm (function) chỉ nên thực hiện một việc duy nhất. Bạn có thể tham khảo ví dụ dưới đây:

// DON'T
function getUserRouteHandler (req, res) {
  const { userId } = req.params
  // inline SQL query
  knex('user')
    .where({ id: userId })
    .first()
    .then((user) => res.json(user))
}
// DO
// User model (eg. models/user.js)
const tableName = 'user'
const User = {
  getOne (userId) {
    return knex(tableName)
      .where({ id: userId })
      .first()
  }
}
// route handler (eg. server/routes/user/get.js)
function getUserRouteHandler (req, res) {
  const { userId } = req.params
  User.getOne(userId)
    .then((user) => res.json(user))
}

Việc đặt tên hàm cũng có những lưu ý tương tự như với đặt tên biến, không ngại đặt tên dài và cần có ý nghĩa gợi ý dễ tìm kiếm. Thông thường tên hàm sẽ là một động từ hoặc cụm động từ thể hiện chức năng mà hàm đó thực hiện.

// DON'T
/**
 * Invite a new user with its email address
 * @param {String} user email address
 */
function inv (user) { /* implementation */ }

// DO
function inviteUser (emailAddress) { /* implementation */ }

Trong trường hợp có nhiều tham số cần truyền vào trong hàm, bạn nên sử dụng cách truyền dạng Object, tốt hơn nữa là có thể model hóa Object đó lên để dễ dàng sử dụng và truyền vào trong lời gọi hàm.

// DON'T
function getRegisteredUsers (fields, include, fromDate, toDate) { /* implementation */ }
getRegisteredUsers(['firstName', 'lastName', 'email'], ['invitedUsers'], '2016-09-26', '2016-12-13')

// DO
function getRegisteredUsers ({ fields, include, fromDate, toDate }) { /* implementation */ }
getRegisteredUsers({
  fields: ['firstName', 'lastName', 'email'],
  include: ['invitedUsers'],
  fromDate: '2016-09-26',
  toDate: '2016-12-13'
})

Một số kinh nghiệm khác dành cho bạn khi viết hàm:

  • Viết các hàm thuần túy (pure functions) không phụ thuộc hay có ảnh hưởng đến các biến, thành phần bên ngoài; giảm tối đa side effects trong hàm, điều này giúp chúng ta dễ dàng sử dụng, kiểm thử mà không lo ảnh hưởng đến chương trình
  • Tổ chức thứ tự các hàm trong source code (trong một file script) theo level từ cao đến thấp; trong trường hợp trong xử lý của function A gọi đến function B thì function nên được đặt ở phía dưới. Điều này tạo ra một logic về thứ tự tự nhiên trong mã nguồn.
  • Tránh việc viết chung xử lý cập nhật/ sửa đổi dữ liệu và truy vấn dữ liệu trong cùng một hàm. Điều này sẽ phát sinh những kết quả không mong muốn trong lời gọi hàm sử dụng.

  [Clean code- JS] Đừng viết switch case như này nữa!

  Viết clean code: Code “đẹp trai” và code “xấu gái” có gì hay ho?

3. Đặt quy tắc viết code chung cho dự án

Trước khi bắt đầu một dự án, viết những dòng code đầu tiên; hãy tạo coding convention cho team của bạn cùng những quy tắc, nguyên tắc chung trong định dạng từ những điều nhỏ nhất như khoảng cách lề, dấu chấm phẩy, … Một gợi ý mà bạn có thể tham khảo là sử dụng Airbnb style dành cho JavaScript

Đặt quy tắc viết code chung cho dự ánĐặt quy tắc viết code chung cho dự án

 

Một ví dụ trong nguyên tắc chung đối với team khi viết code; bạn có thể sử dụng khi viết những đoạn xử lý bất động bộ sử dùng Promise.

asyncFunc1((err, result1) => {
  asyncFunc2(result1, (err, result2) => {
    asyncFunc3(result2, (err, result3) => {
      console.lor(result3)
    })
  })
})
asyncFuncPromise1()
  .then(asyncFuncPromise2)
  .then(asyncFuncPromise3)
  .then((result) => console.log(result))
  .catch((err) => console.error(err))

2 cách viết trên đều có thể được chấp nhận, tuy nhiên cần có sự đồng bộ trong style viết code của cả dự án. Cách viết thứ 2 mang đến sự dễ nhìn, đồng thời có sự rõ ràng trong trình tự các bước xử lý đồng bộ hơn so với cách thứ nhất.

Xem thêm việc làm JavaScript hấp dẫn trên TopDev

4. Cải thiện hiệu suất viết code

Để viết được những đoạn code “tốt” với hiệu suất chạy chương trình ở mức cao; trước tiên hãy bắt đầu với cách viết code đơn giản và rõ ràng. Bạn nên tập sử dụng các công cụ giám sát, đánh giá hiệu suất ứng dụng JavaScript Profiler để xác định, tìm ra những bottlenecks trong chương trình của mình.

Cải thiện hiệu suất viết code

Đừng cố gắng tối ưu, cải thiện hiệu suất ngay từ đầu; điều đó có thể khiến có công việc phát triển dự án của bạn trở nên nặng nề hơn. Hãy tối ưu hóa source code của bạn khi cần thiết và đánh giá tác động thực sự của nó lên dự án mà bạn đang triển khai. Ngoài ra, để cải thiện được hiệu suất, hãy cố gắng tạo ra các bản code mẫu (template) qua từng dự án và có kế hoạch tối ưu nó (upgrade version) một cách đồng bộ. 

Kết bài

Clean Code thực sự là một kỹ năng quan trọng giúp bạn đi xa hơn trở thành một lập trình viên chuyên nghiệp. Mặc dù không dễ để áp dụng những điều trên xuyên suốt dự án của bạn, nhưng hãy bắt đầu thực hành và tạo thói quen ngay từ ban đầu; điều đó sẽ giúp cho những dòng code JavaScript của bạn trở nên sạch đẹp và hiệu quả hơn. Cảm ơn các bạn đã đọc bài và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Xem thêm Việc làm IT hấp dẫn trên TopDev