본문 바로가기
etc.

네이밍 컨벤션 - 이름을 붙이는 것은 원래 어렵습니다

by 돈민찌 2024. 7. 7.
반응형

English language

변수와 함수의 이름을 지을 때는 영어를 사용하세요.

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

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

좋든 싫든 영어는 프로그래밍에서 지배적인 언어입니다. 모든 프로그래밍 언어의 구문은 물론 수많은 문서와 교육 자료가 영어로 작성되어 있습니다. 영어로 코드를 작성하면 코드의 응집력을 크게 높일 수 있습니다.

Naming convention

대/소문자 명명 규칙을 선택하고 이를 따르세요. (언어의 권장사항에 따르길 권장합니다. 자바스크립트의 경우 카멜케이스)

/* Bad */
const page_count = 5;
const active = true;
const ShouldUpdate = true;

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

S-I-D

이름은 짧고, 직관적이며, 설명적이어야 합니다:

  • 짧게. 이름은 입력하는 데 시간이 오래 걸리지 않아야 하며, 따라서 기억하기 쉬워야 합니다;
  • 직관적. 이름은 가능한 한 일반적인 말투에 가깝게 자연스럽게 읽혀야 합니다;
  • 설명적. 이름은 가장 효율적인 방법으로 무엇을 하는/보유하고 있는지를 반영해야 합니다.
/* Bad */
const a = 5; // "a"는 무엇이든 의미할 수 있습니다.
const isPaginatable = a > 10; // "페이지 매김 가능"은 매우 부자연스럽게 들립니다.
const shouldPaginatize = a > 10; // 합성 동사는 정말 재미있어요!

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

Avoid contractions

축약어는 사용하지 마세요. 축약어는 코드의 가독성만 떨어뜨릴 뿐입니다. 짧고 설명적인 이름을 찾는 것이 어려울 수 있지만 축약어를 사용하는 것에 대한 변명은 되지 않습니다.

축약어를 사용할 수 밖에 없는 상황이라면, 실제 사용 사례를 찾아 그나마 보편적인 축약 방식을 사용하세요. (예: Context를 ctx로 축약 표현하는 것)

/* Bad */
function getUsrNme() {
  // ...
}

/* Good */
function getUserName() {
  // ...
}

Avoid context duplication

이름이 정의된 컨텍스트와 중복되지 않아야 합니다. 가독성을 떨어뜨리지 않는다면 항상 이름에서 문맥을 제거하세요.

class UserService {
  /* `userService.getUserSettings()`는 메서드 이름이 컨텍스트("User")와 중복됩니다. */
  getUserSettings(event) {
    // ...
  }

  /* `userService.getSettings()`로 이해하기 쉽고 잘 읽힙니다. */
  getSettings(event) {
    // ...
  }
}

Reflect the expected result

이름은 예상되는 결과를 반영해야 합니다. 또한 사용하는 사례에 적합하게 네이밍을 맞추는 것이 좋습니다.

/* Bad */
const isEnabled = itemCount > 3;
if (!isEnabled) {
  // ...
}

/* Good */
const isDisabled = itemCount <= 3;
if (isDisabled) {
  // ...
}

Naming functions

A/HC/LC Pattern

함수 이름을 지을 때 따라야 할 유용한 패턴이 있습니다:

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

아래 표에서 이 패턴이 어떻게 적용될 수 있는지 살펴보세요.

Name Prefix Action (A) High context (HC) Low context (LC)
getUser   get User  
getUserMessages   get User Messages
shouldDisplayMessage should Display Message  
isPaymentEnabled is Enabled Payment  

Actions

함수 이름의 동사 부분입니다. 함수가 하는 일을 설명하는 가장 중요한 부분입니다.

get

데이터에 즉시 액세스합니다(예: 내부 데이터의 속기 가져 오기). 언어가 getter를 지원하는 경우에는 getter를 사용합니다.

function getUserFullName() {
  return this.firstName + ' ' + this.lastName;
}

compose도 참조하세요.

set

선언적 방식으로 변수를 설정합니다 (값 A를 값 B로). 언어가 setter를 지원하는 경우에는 setter를 사용합니다.

let fruits = 0;

function setFruits(nextFruits) {
  fruits = nextFruits;
}

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

reset

변수를 초기 값 또는 상태로 되돌립니다.

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

function resetFruits() {
  fruits = initialFruits;
}

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

fetch

불확실한 시간이 걸리는 일부 데이터를 요청합니다(예: 데이터베이스 요청).

async function fetchUsers() {
  return this.userRepository
    .createQueryBuilder()
    .where('user.isActive = :isActive', { isActive: true })
    .getMany();
}

remove

어딘가에서 (무언가로부터) 제거합니다.

예를 들어 검색 페이지에 선택된 필터 컬렉션이 있는 경우 컬렉션에서 필터 중 하나를 제거하는 것은 removeFilter이지 deleteFilter가 아닙니다(영어에서도 자연스럽게 이렇게 말하게 됩니다):

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

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

delete도 참조하세요.

delete

존재 영역에서 무언가를 완전히 지웁니다. (삭제합니다.)

여러분이 콘텐츠 편집자이고, 삭제하고 싶은 악성 게시물이 있다고 가정해 봅시다. 반짝이는 "글 삭제" 버튼을 클릭하면 CMS는 removePost가 아닌 deletePost 작업을 수행합니다.

function deleteUser(id) {
  return this.userRepository.delete(id);
}

remove도 참조하세요.

compose

기존 데이터에서 새 데이터를 생성합니다. 주로 문자열, 객체 또는 함수에 적용됩니다.

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

get도 참조하세요.


Context

함수가 작동하는 도메인입니다.

함수는 종종 무엇에 대한 작업입니다. 작동 가능한 도메인이 무엇인지 또는 최소한 예상되는 데이터 유형을 명시하는 것이 중요합니다.

/* 프리미티브로 작동하는 순수 함수 */
function filter(list, predicate) {
  return list.filter(predicate);
}

/* 게시물에서 정확하게 작동하는 기능 */
function getRecentExams(exams) {
  return filter(exams, (post) => post.date === Date.now());
}

일부 언어별 가정에 따라 문맥을 생략할 수 있습니다. 예를 들어, 자바스크립트에서는 filterArray에서 작동하는 것이 일반적입니다. 명시적으로 filterArray를 추가할 필요가 없습니다.


Prefixes

접두사는 변수의 의미를 강화합니다. 함수 이름에는 거의 사용되지 않습니다.

is

현재 컨텍스트의 특성 또는 상태를 설명합니다(일반적으로 boolean).

const color = 'blue';
const isBlue = color === 'blue'; // 특성
const isPresent = true; // 상태

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

has

현재 컨텍스트가 특정 값이나 상태를 가지고 있는지 여부를 설명합니다(보통 boolean).

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

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

should

특정 동작과 결합된 긍정 조건문(보통 boolean)을 반영합니다.

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

min/max

최소값 또는 최대값을 나타냅니다. 경계 또는 한계를 설명할 때 사용합니다.

/**
 * 지정된 최소/최대 범위 내에서 임의의 양의 게시물을 렌더링합니다.
 */
function renderExams(exams, minExams, maxExams) {
  return exams.slice(0, randomBetween(minExams, maxExams));
}

Singular and Plurals

접두사와 마찬가지로 변수 이름은 단일 값을 포함하는지 또는 여러 값을 포함하는지에 따라 단수 또는 복수로 만들 수 있습니다.

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

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

datas와 같은 실제로 영어에서 사용되지 않는 단어로 변수명을 사용하게 될 경우가 있는데, 가능한 한 지양합니다. (사실 이 경우에는 도메인을 정확히 반영하지 못할 것으로 보이는 data를 컨텍스트 이름으로 사용하는 것부터 재고려해야 합니다.)

반응형

댓글