변수는 어떻게 지어야 할까?

djunnni·2021년 3월 1일
2

Computer Science

목록 보기
1/4

서론

개발을 하다보면 변수를 어떻게 지을지 고민할 때가 있다.
비슷한 의미로 사용하다보면 다음에 맡을 사람에게 큰 고민거리가 될 것 같다.

 // ex)
router.post('api/notices/', async (req,res) => {
	const { target } = req.body;
	// target은 개인이 될 수도, 전체가 될 수도, 그룹이 될 수도 있다.
});

여기서 방법은 다양할 것 같다.

  1. 개인, 전체, 그룹에 대한 각각의 api를 만든다.
  2. target으로 구분을 하고 Id를 따로 받는다.

여기서 변수의 이름을 어떻게 지어야 좋을 지 찾아보던 중 kettanaito/naming-cheatsheet 를 보고 공유하면 좋을 것 같았다.

본론

무언가에 대해 이름을 짓는 건 어렵다. 지금부터 쉽게 짓는 연습을 해보자.

여기서 제안하는 방법이 모든 프로그래밍 언어에 적용되진 않지만 자바스크립트에서 사용하기엔 괜찮다고 본다.

1. 영어

변수나 함수의 이름을 지을 때, 영어를 쓰자.

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

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

좋든 싫든 영어는 프로그래밍에 있어 가장 보편적인 언어다. 모든 프로그래밍 언어의 문법또한 영어를 기초로 하고 있다. 영어로 작성된 코드는 응집력(이해력)을 상승시킨다.

2. 이름 짓기 규칙

이름을 지을 때는 CamelCase, PascalCase, snake_case, 등 그 밖에 규칙들을 이용해서 지어라. 그리고 한가지 규칙만을 주로 이용해서 코드를 작성하라.

/* 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

개인적으로는 camelCase를 사용하는게 편했다.
이유는 javascript eslint에서 snake_case를 이용하면 warning이 나오기도 하고 그밖에 코드를 짜다보면 습관이 되서 그런 것 같다.

3. S-I-D

이름은 짧고, 명쾌하고, 설명이 가능해야 된다.

짧다 - 이름은 입력하는데 길면 불편하다 그러니 기억하는 편이 좋다.
명쾌하다 - 읽기 자연스럽고 공통적으로 사용되는 단어를 이용해라
설명가능하다 - 단어는 반드시 효율적인 방법으로 이루어 져야한다.

/* 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

4. 함축적인 표현을 피하라

함축적인 표현을 피하라. 코드의 가독성을 저하시키지 말자. 짧고, 설명 가능한 이름으로 작성해보자. 어려울 것으로 보이지만 함축적인 푷현은 다른사람들에게도 이해를 시키는데 시간을 쓰게 한다.

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

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

5. 중복되는 맥락은 피하자

이미 정의된 맥락에서 또다시 함수 이름에 표시되는 건 피하자. 항상 가독성에 저하가 되는지 구분하고 있다면 제거하자.

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

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

6. 예상되는 결과가 노출되게 하자

이름은 반드시 예상된 결과를 노출해야 된다.

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

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

어느정도 동의한다.
그러나 버튼이 2개 이상이 있고 사용가능한지 여부에 따라 갈린다면 굳이 변수를 2개 만들 필요는 없다고 본다.
이 때, 나라면 isEnabled로만 구분을 할 것 같다.

7. 이름 짓기

A/HC/LC 패턴

이름 짓기 유용한 패턴을 보자

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

이 패턴이 어떻게 적용되는지 테이블로 구분해보자

nameprefixaction (A)high context (HC)low context (LC)
getUsergetUser
getUserMessagesgetUserMessages
handleClickOutsidehandleClickOutside
shoudDisplayMessageshouldDisplayMessage

context의 순서는 변수의미에 영향을 끼친다. 예를 들어보면 shouldUpdateComponent 는 당신이 컴포넌트를 업데이트 시키겠다는 의미가 강하지만 shouldComponentUpdate는 컴포넌트가 스스로 업데이트 하겠다는 의미가 강하다. 따라서 high context에 따라 의미가 바뀐다.

앞으로 이부분에 중점을 두고 지어야 겠다.

Actions

함수 이름의 동사 부분이다. 함수가 수행할 것에 대해 설명하는 게 드러나야 한다.

get

데이터를 즉시 접근할 때, ( 내부 데이터로 부터 get 할 떄, )

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

set
명시된 방법으로 변수를 넣을 때,

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
일정 시간동안 걸려 데이터를 요청할 때, ( 비동기 통신 등 )

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

remove
요소를 빼내거나 지울 때,

예를 들면, 검색 페이지에서 필터 요소가 있다고 하자. 만약 필터를 제거하고 싶을 때 removeFilter가 어울리지 deleteFilter는 삭제한다는 의미가 강하다. ( 영어의 의미에 따라 사용을 다르게 하자 )

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

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

delete
존재하고 있는 실체를 완전히 지울 떄,

예를 들면, 클라우드에 이미지를 업로드 했다고 하자. 거기서 특정 이미지를 제거하고 싶다. 이 때, deleteImageremoveImage보다 더 낫다.

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

compose
이미 존재하는 데이터로 부터 새로운 데이터를 만들어 낼 때, string, object, function에 어울린다.

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

handle
액션을 다룰 때, 콜백 메서드로 자주 사용한다.

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

link.addEventListener('click', handleLinkClick)

8. 맥락

영역의 의미를 보고 동작에 대해 살펴보자
이미 리스트에 대한 필터를 한다고 했을 때, filter만 적으면 되지 filterArray로 적을 필요가 없다.

/* 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())
}

9. Prefixes

Prefixes는 변수의 의미를 강화시켜줄 때가 있는데 함수 이름에서는 거의 사용되지 않는다.

is
현재 상태 값을 표현할 때, 자주 쓴다 (boolean)

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

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

has
상태나 값에서 이미 가지고 있을 때,

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

/* Good */
const hasProducts = productsCount > 0

array에서 특정 string을 포함할 때, 사용해도 괜찮은 것 같다.

should
상태가 변경되어야 할 때,

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

min / max

/**
 * 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

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

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

  this.setState({ posts: nextPosts })
}

10. 단수 / 복수

prefix 처럼 단수 복수도 변수를 상징하는데에 중요한 역할을 한다.

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

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

이 부분이 지켜져야 협업을 한다해도 Object가 오는 지, Object Array가 오는 지 구분이 되기 때문이다.

reference

[Github] kettanaito/naming-cheatsheet

profile
https://djunnni.tistory.com/ 로 이전합니다.

1개의 댓글

comment-user-thumbnail
2022년 5월 12일

좋은 글 감사합니다:)

답글 달기

관련 채용 정보