카테고리 없음

JS 클린코드-함수편(1)

by GicoMomg 2022. 1. 20.

🤔 이번 시간에는 자바스크립트 클린코드, 함수편 일부를 공부해보았다!

-함수 인자는 이상적으로 2개 이하가 좋다.
-하나의 함수에는 하나의 책임을 주자
-매개변수로 플래그를 사용하지 말자
-조건문을 캡슐화 하자
-부정조건문을 사용하지 말자
-조건문 작성을 지양하자


(1) 함수 인자는 이상적으로 2개 이하가 좋다.

  • 매개변수의 개수를 제한하면, 함수 테스팅을 좀 더 용이하게 할 수 있다.
  • 만약 인자수가 많으면 테스트해야할 경우의 수가 많아지며 이는 많은 시간을 소요하게 한다.
  • 또한 함수에 많은 인자가 있다는 건, 해당 함수가 많은 역할을 한다는 말도 된다.

🙄 하지만 전 정말 3개 이상의 매개변수를 받아야 하는데요?


  • 그렇다면, 매개변수를 받을 때 객체 형태로 받는 게 좋다.
// Bad
function customAlert(title, body, btnText, hasConfirm) {
  // ...
}
// Good
function customAlert({title, body, btnText, hasCloseBtn}) {
  // ...
}

customAlert({
  title: '성공!'
  body: '가입이 완료되었습니다.'
  btnText: '메인 사이트로 이동하기'
  hasCloseBtn: true,
})



(2) 하나의 함수에는 하나의 책임만 주자

  • 하나의 함수가 여러 책임을 가지고 있는 건 좋지 않다.
  • 먼저 눈에 띄는 현상으로는 코드의 길이가 늘어날 것이며, 다른 개발자가 보았을 때 해당 함수의 역할을 쉽게 이해하기 어렵다. (이름도 짓기 어려워짐)
  • 또한, 하나의 함수가 여러 역할을 하기에 테스트를 하기도 쉽지 않다.
  • 아래 예시는 체크가 완료된 음식 객체의 콜백 함수를 실행하는 모습이다.
// Bad
function emailClients(clients) {
  clients.forEach(client => {
    const clientRecord = database.lookup(client);
    if (clientRecord.isActive()) {
      email(client);
    }
  });
}
// Good
function emailClients(clients) {
  clients
    .filter(isClientActive)
    .forEach(email);
}

function isClientActive(client) {
  const clientRecord = database.lookup(client);
  return clientRecord.isActive();
}



(3) 매개변수로 플래그를 사용하지 말자

  • 플래그란, 특정 로직의 흐름을 제어하기 위한 boolean을 말한다.
  • 플래그를 사용한다는 건, 해당 함수가 한 가지 이상의 일을 한다는 의미가 된다.
  • 그러므로 boolean을 기반으로 함수를 동작시키지 말고, 함수를 분리시키자.
// Bad
function createFile(name, temp) {
  if (temp) {
    fs.create(`./temp/${name}`);
  } else {
    fs.create(name);
  }
}
// Good
function createFile(name) {
  fs.create(name);
}
function createTempFile(name) {
  createFile(`./temp/${name}`);
}



(4) 조건문을 캡슐화하자

  • 우리는 조건문을 사용해, 조건에 따른 다른 처리를 진행한다.
  • 아래 코드와 같이 조건문 내부에 길게 코드를 작성할 수도 있다.
// Bad
if (userStatus === 'login' && url === 'home') {
  // ...
}
  • 하지만 조건문을 바로 적어버리면 해당 조건문이 어떤 의미를 가지는 게 알기 어렵다.
  • 아래와 같이 조건문을 캡슐화해서 생성하여 사용하도록 하자.
// Good
function isUserVaild() {
  return userStatus === 'login' && url === 'home';
}
if (isUserVaild) {
  // ...
}



(5) 부정조건문을 사용하지 말자

  • xxxNot!을 사용해 !xxxxNot과 같은 형태를 사용하지 말자.
// Bad
if (!isUserNotVaildToken) {
  // ...
}

// Good
if (isUserVaildToken) {
  // ...
}



(6) 조건문 작성을 지양하자

  • 함수나 클래스에 많은 조건문이 존재한다면 해당 함수는 1가지 이상의 일을 수행하고 있는 것이다.
  • 여러 개의 조건문은 상속을 사용해 각 함수의 책임을 분리시킬 수 있다.
// Bad
class Car {
  getCruisingAltitude() {
    switch (this.type) {
      case '777':
        return this.getMaxAltitude() - this.getPassengerCount();
      case 'Air Force One':
        return this.getMaxAltitude();
      case 'Cessna':
        return this.getMaxAltitude() - this.getFuelExpenditure();
    }
  }
}
// Good
class Airplane {
  // ...
}

class Boeing777 extends Airplane {
  getCruisingAltitude() {
    return this.getMaxAltitude() - this.getPassengerCount();
  }
}
class AirForceOne extends Airplane {
  getCruisingAltitude() {
    return this.getMaxAltitude();
  }
}
class Cessna extends Airplane {
  getCruisingAltitude() {
    return this.getMaxAltitude() - this.getFuelExpenditure();
  }
}

반응형

댓글