코딩 잘하는 팁 세가지

SangHun Park·2023년 1월 10일
0

출처: 코딩 잘하는 팁 세가지 (이걸 알면 코드가 깔끔해 진다)

DRY (Don't Repeat Yourself)

DRY 예시 1

수정 전

function greetings(user) {
  return `Hi ${user.firstName} ${user.lastName}`
}

function goodbye(user) {
  return `See you next time ${user.firstName} ${user.lastName}`
}

수정 후

class를 선언하여 중복 로직을 하나의 함수를 호출하도록 개선이 가능하다.

function greetings(user) {
  return `Hi ${user.fullName()}`
}

function goodbye(user) {
  return `See you next time ${user.fullName()}`
}

class User {
  fullName() {
    return `${this.firstName} ${this.middleName} ${this.lastName}`
  }
}

DRY 예시 2

아래 코드는 중복적 요소로 보이지만 한 가지의 로직을 함수 안에서 처리하고 있고 이 로직이 다른 곳에서 중복적으로 사용되지 않고 있기 때문에 DRY라고 할 수 없다.

function validateBody(body) {
  if (!body.id) {
    throw new Error('Validation failed. The attribute id is missing.');
  }

  if (!body.name) {
    throw new Error('Validation failed. The attribute name is missing.');
  }

  if (!body.count) {
    throw new Error('Validation failed. The attribute count is missing.');
  }
}

중복적 선언이라고 해서 DRY라고 판단하지 않고 로직, 의도, 비즈니스 로직을 고려하여 판단해야 한다.

위 소스는 아래와 같이 선언할 수는 있음. (참고용)

function validateBody(body) {
  const attributes = ['id', 'name', 'count'];
  attributes.forEach(attribute => {
    if (!body[attribute]) {
      throw new Error(
        `Validation failed. The attribute "${attribute}" is missing.`
      );
    }
  })
}

KISS (Keep It Simple, Stupid)

Most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design and unnecessary complexity should be avoided.
대부분의 시스템은 복잡하기보다 단순하게 유지했을때 가장 잘 동작한다.
따라서, 불필요한 복잡성은 피하고 단순함을 추구하는 것이 목표다.

KISS 예제 1

function getFirst(array, isEven) {
  return array.find(x => (isEven ? x % 2 === 0 : x % 2 !== 0));
}

위 소스는 한 줄로 깔끔하게 작성 되어져 있지만 가독성 측면에서 좋지 않을 수 있다. 한 눈에 이해하기가 어려울 수 있기 때문이다.

개선을 위한 코드를 살펴보자.

function getFirst(array, isEven) {
  if (isEven) {
    return array.find(x => x % 2 === 0);
  } else {
    return array.find(x => x % 2 !== 0);
  }
}

위와 같이 소스를 조금 풀어서 가독성을 개선하는 방법을 생각할 수 있다.
하지만 전달 받은 파라미터를 판단하여 분기문으로 처리하는 방식은 단순하지 않을 수 있다.

function getFirstOdd(array) {
  return array.find(x => x % 2 !== 0);
}

function getFirstEven(array) {
  return array.find((x) => x % 2 === 0);
}

각각의 함수로 선언하여 처리할 경우 가독성을 높여 좀 더 단순화 할 수 있다.

KISS 예제 2

UI View를 위한 목적의 로직에서 서버 통신과 같은 로직을 같이 선언하기 보다는

class LoginView {
  display() {
    // display view..
  }

  onLoginButtonClick() {
    fetch('https://server.com')
      .then(data => data.json())
      .then(data => {
        if (data.token) {
          localStorage.setItem('TOKEN', data.token);
          // update UI elements
        } else {
          // ...
        }
      })
      .catch(error => {
        if (error.statusCode === 500) {
          // retry fetch?
        } else if (error.statusCode === 400) {
          // handle an error
        }
        // show error message
      })
  }
}

아래와 같이 View와 별도의 통신 로직을 class로 분리함으로써 코드의 복잡성을 줄이고 이해하기 쉽게 만들 수 있다.
또한 테스트 코드에서도 활용하기 더 좋다.

class LoginView {
  constructor(userPresenter) {
    this.userPresenter = userPresenter;
  }

  display() {
    // display view..
  }

  onLoginButtonClick() {
    this.userPresenter
      .login()
      .then(result => {
        // update text UI element with result.displayMessage
        // update button UI element with result.buttonText
      })
  }
}

class UserPresenter {
  userService;
  login() {
    this.userService
      .login()
      .then(result => {
        if (result.success) {
          localStorage.setItem('TOKEN', result.token);
          return {
            displayMessage: result.message,
            buttonText: 'Go Home',
          };
        } else {
          return {
            diplayMessage: 'Unable to login',
            buttonText: 'Ok',
          };
        }
      })
      .catch(error => {
        // Something really went wrong! 
      });
  }
}

YAGNI (You Ain't Gonna Need It)

현재는 DB에서 사용자 정보만 삭제하면 되지만 나중을 위해 DB를 삭제하지 않고 삭제 처리된 것 처럼 처리할 수 있는 기능을 추가하였다.

function deleteUser(id, softDelete = false) {
  if (softDelete) {
    return this._softDelete(id);
  }
  return db.removeById(id);
}

위와 같은 기능을 추가할 경우 delete 이외의 다른 로직에서도 동일한 코딩을 필요하지 않음에도 추가하는 불필요한 작업이 추가 될 수 있다.
미래에 필요하다고 생각되는 기능을 불필요하게 추가하지 않도록 한다.

0개의 댓글