Bài viết này mình sẽ nói về các quy tắc đặt tên trong lập trình. Nếu các bạn có thể áp dụng các quy tắc này vào việc đặt tên thì code của bạn chắc chắn sẽ dễ đọc hơn rất nhiều!

English language

Sử dụng ngôn ngữ tiếng Anh khi đặt tên cho các biến và hàm của bạn.

/* Bad */
const primerNombre = 'Gustavo';
const amigos = ['Kate', 'John'];

/* Good */
const firstName = 'Gustavo';
const friends = ['Kate', 'John'];

Dù muốn hay không, tiếng Anh là ngôn ngữ chính trong lập trình: cú pháp của tất cả các ngôn ngữ lập trình đều được viết bằng tiếng Anh, cũng như vô số tài liệu và tài liệu học tập. Bằng cách viết code của bạn bằng tiếng Anh, bạn tăng đáng kể tính liên kết của nó.

Naming convention

Chọn một quy ước đặt tên và làm theo nó. Nó có thể là camelCase, PascalCase, solid_case hoặc bất cứ thứ gì khác, miễn là nó vẫn nhất quán. Nhiều ngôn ngữ lập trình có truyền thống riêng về quy ước đặt tên; kiểm tra tài liệu về ngôn ngữ của bạn hoặc nghiên cứu một số repository phổ biến trên Github!

/* Bad */
const page_count = 5;
const shouldUpdate = true;

/* Good */
const pageCount = 5;
const shouldUpdate = true;

/* Good as well */
const page_count = 5;
const should_update = true;

S-I-D

Một cái tên phải ngắn gọn, trực quan, mang tính mô tả:

  • Ngắn gọn. Tên phải không mất thời gian khi viết và do đó, hãy nhớ;
  • Trực quan. Tên phải đọc một cách tự nhiên, càng gần với lời nói phổ thông càng tốt.
  • Môt tả. Tên phải phản ánh những gì nó làm / sở hữu theo cách hiệu quả nhất.
/* Bad */
const a = 5; // "a" could mean anything
const isPaginatable = a > 10; // "Paginatable" sounds extremely unnatural
const shouldPaginatize = a > 10; // Made up verbs are so much fun!

/* Good */
const postCount = 5;
const hasPagination = postCount > 10;
const shouldPaginate = postCount > 10; // alternatively

Avoid contractions

Không sử dụng viết tắt. Chúng không đóng góp gì nhưng giảm tính đọc hiểu của code. Tìm một cái tên ngắn gọn, mang tính mô tả có thể khó, nhưng sự co lại không phải là cái cớ để không làm như vậy.

/* Bad */
const onItmClk = () => {};

/* Good */
const onItemClick = () => {};

Avoid context duplication

Tên không được trùng lặp với ngữ cảnh mà nó được xác định. Luôn xóa ngữ cảnh khỏi tên nếu điều đó không làm giảm khả năng đọc hiểu của nó.

class MenuItem {
  /* Method name duplicates the context (which is "MenuItem") */
  handleMenuItemClick = (event) => { ... }

  /* Reads nicely as `MenuItem.handleClick()` */
  handleClick = (event) => { ... }
}

Reflect the expected result

Tên phải phản ánh kết quả mong đợi.

/* Bad */
const isEnabled = itemCount > 3;
return <Button disabled={!isEnabled} />;

/* Good */
const isDisabled = itemCount <= 3;
return <Button disabled={isDisabled} />;

Naming functions

A/HC/LC Pattern

Có một mô hình hữu ích cần tuân theo khi đặt tên cho các hàm:

prefix? + action (A) + high context (HC) + low context? (LC)

Hãy xem cách mô hình này có thể được áp dụng trong bảng dưới đây.

Name Prefix Action (A) High context (HC) Low context (LC)
getUser   get User  
getUserMessages   get User Messages
handleClickOutside   handle Click Outside
shouldDisplayMessage should Display Message  

Lưu ý: Thứ tự của ngữ cảnh ảnh hưởng đến ý nghĩa của một biến. Ví dụ: shouldUpdateComponent có nghĩa là bạn sắp cập nhật một component, trong khi shouldComponentUpdate cho bạn biết rằng component sẽ tự cập nhật và bạn đang kiểm soát khi nào nó nên được cập nhật. Nói cách khác, hight context nhấn mạnh ý nghĩa của một biến.


Actions

Phần động từ của tên hàm của bạn. Phần quan trọng nhất chịu trách nhiệm mô tả hàm làm cái gì.

get

Truy cập dữ liệu ngay lập tức (tức là bộ lấy dữ liệu nội bộ viết tắt).

function getFruitCount() {
  return this.fruits.length;
}

Xem thêm compose.

set

Gắn một biến trong một cách khai báo, với giá trị A đến giá trị B.

let fruits = 0;

function setFruits(nextFruits) {
  fruits = nextFruits;
}

setFruits(5);
console.log(fruits); // 5

reset

Gắn một biến trở lại với giá trị hoặc trạng thái ban đầu của nó.

const initialFruits = 5;
let fruits = initialFruits;
setFruits(10);
console.log(fruits); // 10

function resetFruits() {
  fruits = initialFruits;
}

resetFruits();
console.log(fruits); // 5

fetch

Yêu cầu một số dữ liệu, mất một thời gian không xác định (tức là yêu cầu không đồng bộ).

function fetchPosts(postCount) {
  return fetch('https://api.dev/posts', {...})
}

remove

Loại bỏ một cái gì đó từ một nơi nào đó.

Ví dụ, nếu bạn có một danh sách của bộ lọc được chọn trên một trang tìm kiếm, xóa một trong số chúng từ danh sách là removeFilter, không phải deleteFilter (và đây cũng là cách bạn nói nó một cách tự nhiên trong tiếng Anh):

function removeFilter(filterName, filters) {
  return filters.filter((name) => name !== filterName);
}

const selectedFilters = ['price', 'availability', 'size'];
removeFilter('price', selectedFilters);

Xem thêm delete.

delete

Hoàn toàn xóa một cái gì đó khỏi các lĩnh vực tồn tại.

Hãy tưởng tượng bạn là một biên tập nội dung và có một bài đăng khét tiếng mà bạn muốn loại bỏ. Sau khi bạn nhấp vào nút “Xóa bài đăng” sáng bóng, CMS thực hiện hành động deletePost, không phải ` removePost`.

function deletePost(id) {
  return database.find({ id }).delete();
}

Xem thêm remove.

compose

Tạo dữ liệu mới từ dữ liệu hiện có. Hầu hết áp dụng cho chuỗi, đối tượng hoặc hàm.

function composePageUrl(pageName, pageId) {
  return pageName.toLowerCase() + '-' + pageId;
}

Xem thêm get.

handle

Xử lý một hành động. Thường được sử dụng khi đặt tên một callback method.

function handleLinkClick() {
  console.log('Clicked a link!');
}

link.addEventListener('click', handleLinkClick);

Context

Một miền mà một chức năng hoạt động trên đó.

Một hàm thường là một hành động trên something. Điều quan trọng là phải nêu rõ miền có thể hoạt động của nó là gì, hoặc ít nhất là một kiểu dữ liệu mong đợi.

/* A pure function operating with primitives */
function filter(list, predicate) {
  return list.filter(predicate);
}

/* Function operating exactly on posts */
function getRecentPosts(posts) {
  return filter(posts, (post) => post.date === Date.now());
}

Một số giả định theo ngôn ngữ cụ thể có thể cho phép bỏ qua ngữ cảnh. Ví dụ, trong JavaScript, thông thường filter hoạt động trên Array. Việc thêm filterArray rõ ràng là không cần thiết.

Prefixes

Tiền tố tăng ý nghĩa của một biến. Nó hiếm khi được sử dụng trong tên hàm.

is

Mô tả một đặc điểm hoặc trạng thái của ngữ cảnh hiện tại (thường là boolean).

const color = 'blue';
const isBlue = color === 'blue'; // characteristic
const isPresent = true; // state

if (isBlue && isPresent) {
  console.log('Blue is present!');
}

has

Mô tả liệu ngữ cảnh hiện tại có sở hữu một giá trị hoặc trạng thái nhất định hay không (thường là boolean).

/* Bad */
const isProductsExist = productsCount > 0;
const areProductsPresent = productsCount > 0;

/* Good */
const hasProducts = productsCount > 0;

should

Phản ánh một câu điều kiện khẳng định (thường là boolean) cùng với một hành động nhất định.

function shouldUpdateUrl(url, expectedUrl) {
  return url !== expectedUrl;
}

min/max

Đại diện cho một giá trị tối thiểu hoặc tối đa. Được sử dụng khi mô tả ranh giới hoặc giới hạn.

/**
 * Renders a random amount of posts within
 * the given min/max boundaries.
 */
function renderPosts(posts, minPosts, maxPosts) {
  return posts.slice(0, randomBetween(minPosts, maxPosts));
}

prev/next

Cho biết trạng thái trước đó hoặc trạng thái tiếp theo của một biến trong ngữ cảnh hiện tại. Được sử dụng khi mô tả sự chuyển đổi trạng thái.

function fetchPosts() {
  const prevPosts = this.state.posts;

  const fetchedPosts = fetch('...');
  const nextPosts = concat(prevPosts, fetchedPosts);

  this.setState({ posts: nextPosts });
}

Singular and Plurals

Giống như tiền tố, những tên biến có thể được đặt ở dạng số ít hoặc số nhiều tùy thuộc vào việc chúng chứa một giá trị duy nhất hoặc nhiều giá trị.

/* Bad */
const friends = 'Bob';
const friend = ['Bob', 'Tony', 'Tanya'];

/* Good */
const friend = 'Bob';
const friends = ['Bob', 'Tony', 'Tanya'];

Reference

  • https://github.com/vovantamvn/naming-cheatsheet
  • https://github.com/kettanaito/naming-cheatsheet

Bản dịch hiện vẫn chưa hoàn thiện, nếu bạn nào muốn đóng góp cho bản dịch hoàn thiện thêm thì có thể tạo PR. Mình xin cám ơn!