[리펙토링] 긴 함수 내부에 작은함수로 쪼개기

chosh·2023년 6월 5일
0

첫번째

많이 추천하는 변수와 함수정의와 로직의 위치

const doSomething = (value) => {
  const copiedValue = [...value]
  
  const firstDo = () => {
    console.log('첫번째 할 일')
    console.log(copiedValue)
  }
  
  const secondDo = () => {
    console.log('두번째 할 일')
  }
  
  const thirdDo = () => {
    console.log('세번째 할 일')
  }
  
  try {
    firstDo()
    secondDo()
    thirdDo()
  } catch (e) {
     console.log("Error: ", e) 
  }
}
  • 변수를 제일 상단에 두고
  • 함수 정의를 두고
  • 함수 실행하는 로직을 하단에 둔다

내 생각

변수와 로직을 멀리 둬도 되는건가?
이 함수에 구현 부분만 빨리 보고 싶은데 제일 아래로 내려가야 되나?

두번째

변수랑 로직이랑 떨어져있어서 이렇게 바꾸면 안되려나?

const doSomething = (value) => {
  const copiedValue = [...value]

  try {
    firstDo()
    secondDo()
    thirdDo()
  } catch (e) {
     console.log("Error: ", e) 
  }
  
  function firstDo(){
    console.log('첫번째 할 일')
    console.log(copiedValue)
  }
  
  function secondDo(){
    console.log('두번째 할 일')
  }
  
  function thirdDo(){
    console.log('세번째 할 일')
  }
}
  • 선언식으로 작성한 함수는 호이스팅이 되기 때문에 하단에 정의
  • 변수와 로직이 가까히 있어서 보기 편한거 같음
  • 하지만 함수의 구현사항을 자연스럽게 읽고 로직을 읽는게 편하다는 의견에는 좋지 않음(위에서 아래로)

내생각

내부 함수의 함수명만 알기 쉽게 작성하면 문제가 없지 않을까?

더 깊이 알고 싶은 함수만 가서 확인하면 되지 않을지..

근데 함수안에 함수안에… 이런식으로 깊어지면 함수의 구현 사항을 먼저 보고 로직을 보는게 좋을거 같기도 함

이제 제일 좋겠다 생각했었음

세번째

그럼 변수를 내리면?

const doSomething = (value) => {
  const firstDo = () => {
    console.log('첫번째 할 일')
    console.log(copiedValue)
  }
  
  const secondDo = () => {
    console.log('두번째 할 일')
  }
  
  const thirdDo = () => {
    console.log('세번째 할 일')
  }
  
  const copiedValue = [...value]

  try {
    firstDo()
    secondDo()
    thirdDo()
  } catch (e) {
     console.log("Error: ", e) 
  }  
}
  • 이건 당연히 에러 발생 (변수의 호이스팅 관련 문제)

네번째

네번째는 잠깐 내부함수에 대해서 고민된 내용

const doSomething = (value) => {
  const copiedValue = [...value]
  
  const firstDo = () => {
    console.log('첫번째 할 일')
    console.log(copiedValue)
  }
  
  const secondDo = (value) => {
    console.log('두번째 할 일')
    console.log(value)
  }
  
  const thirdDo = () => {
    console.log('세번째 할 일')
  }
  
  try {
    firstDo()
    secondDo(copiedValue)
    thirdDo()
  } catch (e) {
     console.log("Error: ", e) 
  }
}
  • firstDo와 secondDo의 차이
  • 함수 내부에서 그냥 값을 사용할건지, 인자로 전달받아서 사용할 건지

내생각

처음에는 이 스코프 안에서 사용할 함수이고,
외부로 뺄때는 프로퍼티랑 인자만 넣어주면 되는데,
굳이 인자로 전달받아야 되나? 싶었음

다섯번째

변수랑 멀리 떨어져 있어도 로직 구현 부분 읽을때 알 수 있으면 상관없을거 같음

const doSomething = (values) => {
  const copiedValues = [...values]
  
  const firstDo = (values) => {
    console.log('첫번째 할 일')
    console.log(values)
  }
  
  const secondDo = () => {
    console.log('두번째 할 일')
  }
  
  const thirdDo = (values) => {
    console.log('세번째 할 일')
    console.log(values.map((data)=> `가공한값 ${data}`))
  }
  
  try {
    firstDo(copiedValue)
    secondDo()
    thirdDo(copiedValue)
  } catch (e) {
     console.log("Error: ", e) 
  }
}
  • 제일 위에서 변수는 어떤 값을 가지고있구나 확인
  • 함수의 구현 내용 확인
  • 로직 부분에서 함수명(무슨일 하는지)과 변수명(무슨값으로 하는지) 를 확인하면 됨

내 생각

지인 개발자분께서 언제든 외부로 뺄수 있기 때문에 순수함수로 구현을 많이 한다라고 하셨었는데,
변수를 표현하려다보니 이름이 너무 길었고
그래서 가독성을 더 해치는거 같아 내부함수에서는 그냥 가져다 쓰는 방식으로 구현을 하려고 했었다
근데 막상 수정하고 보니 어떤 함수에서 무슨일 하는지 어떤 변수를 어디서 쓰는지 왔다갔다 확인해야 됐었고,
구현부분만 확인하는 경우는 거의 없었기 때문에

5번째 방식이 제일 좋은거 같았음
1. 변수 -> 함수 정의 -> 로직 구현 순으로 작성하기
2. 함수는 큰 개념부터 작은개념으로 내려가기
3. 인자로 모두 빼서 순수함수로 구현하기

profile
제가 참고하기 위해 만든 블로그라 글을 편하게 작성했습니다. 틀린거 있다면 댓글 부탁드립니다.

0개의 댓글