클린코드와 내생각

1TBhard·2021년 9월 4일
0
post-thumbnail

대학생 때는 주로 혼자만의 소스코드를 작성해서 코드를 작성했다. 그러다 보니 변수, 함수명을 내 마음대로 처리할 수 있고 나만이 알아보는 코드만을 작성했었다.
그러나, 현업의 코드들을 받다보니 아래와 같은 애로사항이 꽃피기 시작했다.

  1. 변수명과 코드 스타일들이 통일되지 않아 소스코드를 읽기 어려움
  2. 함수의 로직 코드가 너무 길고 중복되는 코드가 존재해 유지 보수가 어려움
  3. 다른 함수에 의해 종속된 함수가 존재해, 이들의 side effect 가 어떤 것인지 예측하기 힘듦

대표적으로 위 3가지로 인해 프로젝트의 유지 보수가 힘들었다.

이에 나 자신이라도 깨끗한 코드를 작성하고자 Javascript CleanCode 를 찾게 되었고 이를 정리 및 내 생각을 적게 되었다.


1. 변수명

변수명 챕터의 경우, 클린 코드에서 제시한 방법이 좋다고 생각했다.

  • 의미있는 변수명 할당, 의도를 나타내는 변수 사용, 동일한 유형의 변수에 동일한 어휘

    현장의 코드는 주석이 없지만 신기하게도 코드들을 이해할 수 있다.
    그 이유는 변수명만 읽어도 해당 변수가 어떤 행동을 하지는 예측이 가능하기 때문이다.

  • 검색가능한 이름을 사용

    검색하기 쉽게 중복되지 않는 이름을 사용하지 않는 것이 좋다.
    전체 검색을 했을 때 같은 이름의 변수명들이 여러개 있을 때 혼란스러웠다.

  • 자신만 알아볼 수 있는 작명 피하기

    의미가 불분명한 변수는 혼란을 초래한다.
    특히, 인수인계할 때 자기도 알아보기 힘든 경우에는 정말 부끄러워진다.

  • 문맥상 필요없는 것들을 쓰지 않기

  • 기본 매개변수

    기본 매개변수를 사용하여 함수를 더 깔끔하게 표현할 수 있었고
    해당 함수를 모르는 사람이 이를 사용할 때 잚못 사용할 확률이 줄어든다.


2. 함수

  • 함수 인자는 2개 이하가 이상적

    이 부분은 동의하기 힘들었다.
    다수의 props 를 받아 처리하는 react Compnoent의 경우 여러 가지 값을 받아서 사용하기 때문이다.
    물론 컴포넌트를 분리해서 처리를 할 수 있지만 배보다 배꼽이 더 커지는 경우 가 있었다.

  • 함수는 하나의 행동만 수행

    함수는 하나의 행동만 수행하도록하는 것은 좋다고 생각한다.
    여러 기능을 수행하는 경우 복잡성이 올라가고 그만큼 버그가 생길 확률도 올라간다.

  • 함수명은 무엇을 하는지 알 수 있어야 함

    이를 행하면 바로 함수의 행동을 파악할 수 있다.

  • 중복된 코드 작성하지 말기

    중복된 코드가 있다면 해당 코드를 변경할 때 중복되는 코드 또한 변경해야한다.
    따라서 중복된 코드는 유지 보수면에서 좋지 않다.

  • Object.assign() 사용해 기본객체 만들기

    이 부분은 복사한 객체를 변경시 원본 객체도 변경되는 sideEffect 를 피하기 위해 놓은 부분인 것 같다.
    현업에서 Date, Moment 등 시간에 대한 객체들을 다룰 때가 있는데 잘못다루어서 이러한 sideEffect 를 경험한 적이 있었다.
    이를 피하기 위해 함수의 parameter로 객체를 전달할 때 해당 객체의 복사본을 보내는 것이 좋다.

  • 매개 변수로 플래그 세우지 않기

    2개 이상의 일을 진행 → 복잡함 → 버그 확률 증가
    따라서, 플래그 값은 parameter 로 주지 않는 것이 좋다.

  • 사이드 이펙트 피하기

    전역변수 변경 조심
    call by reference 되는 객체는 객체를 복사해서 사용

  • 전역 함수 사용하지 말기

    전역 함수를 정의함으로 써 예상하지 못한 다른 함수를 override 할 수 있고 이는 버그로 이어지기 때문이다.

  • 명령형보다 함수형 프로그래밍으로 지향

    함수형 프로그래밍을 사용하는 가장 큰 이유는 깨끗한 코드로 side Effect를 일으키지 않기 위해 사용하는 것 같다.
    이로 인해 버그가 줄어들고 안전한 코드가 된다는 장점이 있다.

  • 조건문을 캡슐화

    조건문을 함수로 캡슐화하는 것이 나중에 유지 보수면에 더 좋다.
    여러 조건문이 존재한다면 조건문 당 하나의 함수로 만든 후 그 함수들을 전부 실행하는 함수를 만들어 조건문을 처리한다.

  • ! 사용 금지

    코드 가독성을 나쁘게 하여 실행 오류를 발생시키는 원인이다.

  • 조건문 작성 지양

    많은 조건문을 이용할 수록 그 부분은 많은 로직을 가지고 있다.
    → 복잡도가 증가 → 에러 발생 확률 증가

  • 타입 체킹 피하기

    타입에 따라 로직이 분기한다면 그만큼 함수의 복잡도가 올라간다.

  • 과도한 최적화 지양

    배보다 배곱이 더 커질 수 있다.

  • 죽은 코드 지우기

    예를 들어 나중에 사용하지 않는 코드에 대해 주석을 처리한 경우, 왜 이를 주석처리했는지에 대해 혼란이 올 때가 있다.


3. 객체

  • getter, setter 사용

    클래스의 멤버 변수를 직접 사용하기 보다는 setter, getter를 함수로 선언하여 사용하는 것이 좋다.

  • 객체에 비공개 멤버 만들기(클로저 사용)

    클로저를 사용하여 해당 부분을 캡슐화 할 수 있다.


4. 클래스

  • Function.prototype 으로 클래스 사용보다는 ES6 클래스 사용
  • 메소드 체이닝을 사용 (this 를 리턴하며 클래스 메소드를 추가로 연결)
  • 상속보다는 조합을 사용 (has-a가 아닌 is-a 관계일 때 상속을 사용)
    • 인간은 동물이다. (인간 is a mamel)
    • 사람은 손이 있다. (사람 has a hand)

5. SOLID

  • 단일 책임 원칙(Single Responsiblity Principle, SRP)
    • 클래스 수정에 2개 이상의 이유가 있으면 안됨(응집되어 있지 않음)
  • 개방 / 폐쇠 원칙(Open/ Principle, OCP)
    • 확장에 대해 열러있으나 수정에 대해 닫힘
  • 리스코프 치환 원칙(Liskov Substitution Principle, LSP)
    • 자료형 T has a S 라면 T 객체S 객체로 치환할 수 있어야한다는 원칙
  • 인터페이스 분리 법칙(Interface Segregation Principle, ISP)
    • 사용하지 않는 인터페이스에 의존하면 안됨
  • 의존성 역전 원칙(Dependency lnversion Principle, DIP)
    • 상위 모듈은 하위 모듈에 종속되어서는 않됨 (둘다 추상화에 의존해야함)
    • 추상화는 세부사항에 의존하지 않음

비동기

  • 콜백대신 Promise 사용

    비동기 코드 부분에 콜백을 사용한다면 콜백지옥 으로 인해 가독성이 떨어진다.
    Prmoise도 좋지만 async await 을 사용하는 것이 더 코드를 깔끔하게 해준다.

  • Async/Await 사용

    콜백지옥으로 벗어나주는 역활 + 코드가 깔끔해지는 효과를 낼 수 있다.


에러 처리

  • 단순히 에러를 확인만 하지 말자
    • Promise 가 실패된 것을 무시하지 말자

실제 제품에는 error를 캐치한 부분을 에러 메시지로 보여줘야한다!!
사용면에서 일단 에러의 원인을 보여주어 사용자가 직접해결할 수 있는 방법을 제시하는 것이 좋다.
그렇지 않으면 사용자로부터 무수한 항의 요청이 올 것이다..


포맷팅

  • 일괄된 대소문자 이용
  • 함수 호출자와 함수 피호출자는 가깝게 위치(코드 읽기 쉽게됨)

프로젝트를 진행하면 여러 사람들의 코드 스타일들이 다르기 때문에 코드를 읽는 것 조차 어려운 경우가 있다.
이에 일관된 포맷팅이 있어야 코드를 해석하는 것이 쉽다.
이에 관련한 prettier, eslint 등 많은 도구들이 발전한 이유가 있다..


주석

  • 비즈니스 로직이 복잡한 경우에만 주석을 달기
    • 좋은 코드는 변수명으로만 의도를 쉽게 알 수 있는 코드이다.
  • 주석으로 된 코드를 남기지 않기
  • 코드 기록을 주석으로 남기지 말자
  • 코드의 위치를 설명하지 않기

출저

profile
기억을 넘어 습관으로

0개의 댓글