클린코드 정복하기 1주차

wannte·2021년 1월 4일
0

Ch1. 클린코드

  1. 코드가 존재하리라

그들은 우리가 원하는 대로 돌아가는 기계가 나오리라 기대한다. 우리가 그런 기계를 만드는 방법을 찾아내이라 믿는다. 요구사항을 애매하게 주어도 우리 의도를 정확히 꿰뚫어 프로그램을 완벽하게 실행하는 그런 기계말이다.

AI가 코딩을 하는 시대가 도래했지만, 이는 개발을 편리성을 증가시키지, 개발자의 필요가 사라지지 않는다.

  1. 나쁜 코드
    마구잡이로 짜여진 코드들은 결국 프로젝트를 망하게 만든다. 나중에 손보겠다고 다짐하지만, "나중은 결코 오지 않는다".
    나쁜 코드가 쌓일수록 팀 생산성은 떨어지게 된다. 재설계를 하는 과정에서도, 유지보수 팀과 재설계팀의 경주가 시작된다.

좋은 코드를 사수하는 일은 바로 우리 프로그래머들의 책임이다.

  1. 클린 코드란?

클린코드를 작성하는 프로그래머는 빈 캔버스를 우아한 작품으로 바꿔가는 화가와 같다.

저명한 프로그래머들의 클린 코드에 대한 의견들이 나열되며, 이 중 중요하다고 생각하는 포인트들만 정리했다.

  • 논리가 간단해야한다.
  • 의존성을 최대한 줄여라
  • 오류를 철저히 처리해라
  • 한가지를 제대로 해라
  • 잘 쓴 문장처럼 읽히며, 설계자의 의도를 숨기지 않는다.
  • 다른 사람이 읽기 쉽고 고치기 쉽다.
  • 언제나 누군가 주의 깊게 짰다는 느낌을 준다.
  • 중복이 없다.
  • 표현성 : 의미 있는 이름
  • 짐작했던 기능을 각 루틴이 그대로 수행한다면 클린 코드라 불러도 되겠다.

'집합에서 항목 찾기'의 경우, 정보가 데이터베이스인지, 해시 맵인지, 배열인지에 관계없이 반복적으로 사용되는 기능이다. 추상 클래스나, 추상 메소드로 묶어 실제 구현을 감싸는 방식으로 진행한다고 한다. 제너릭을 사용하면, 더 쉽고 직관적이게 구현이 가능할 것이라 생각한다.

  1. 보이스카우트 규칙

캠프장은 처음 왔을 때보다 더 깨끗하게 해놓고 떠나라.

시간이 지날수록 코드가 좋아지는 프로젝트...!

Ch2. 의미 있는 이름

의도를 분명하게 밝혀라

int d; //경과 시간(단위: 날짜수)

int elapsedTimeInDays;
int daysSinceCreation;

주석없이 변수명에서 의도를 들어내라. (elapsed, In, Since)

지뢰 찾기 게임에서 다음의 코드를 아래 처럼 수정한다.

public List<int[]> getThem() {
  List<int[]> list1 = new ArrayList<int[]>();
    for (int[] x : theList)
      if (x[0] == 4)
        list1.add(x);
    return list1;
}
 
 
//수정후
public List<Cell> getFlaggedCells() {
  List<Cell> flaggedCells = new ArrayList<Cell>();
  for (Cell x : gameBoard)
    if (cell.isFlagged())
      flaggedCells.add(cell);
  return flaggedCells;
}

//Class Cell
int[] cell;

private boolean isFagged() {
  if (cell[STATUS_VALUE] == FLAGGED)
    return true;
  return false
}

theList? x[0]가 가지는 의미? 4의 의미? list1의 의미?
int[]를 Cell로 숨기고 isFlagged로 추상화

그릇된 정보를 피하라

  • 실제로 List가 아닌 경우에는 List라는 명명을 피해라(accountList -> accountGroup, bunchOfAccounts, Accounts)
    cf. 리스트의 경우에도 컨테이너의 유형을 이름에 넣지 않는 편이 바람직하다 (짐작하건데, 컨테이너의 유형을 변경할 수 있으며, 이로부터 변수명은 자유로워지기기 위해?)
  • 서로 흡사한 이름을 사용하지 않도록 주의한다. (XYZControllerForEfficientHandlingOfStrings vs XYZControllerForEfficientStorageOfStrings)
  • 유사한 개념은 유사한 표기법을 사용한다.
    코드 자동 완성 기능을 사용하며 경험했듯이, 많은 경우 메소드명을 보고 짐작하고 사용하며, 개발의 속도를 높여준다.

의미 있게 구분하라

  • 연속적인 숫자를 덧붙이는 경우를 지양해라
public static void copyChars(char[] a1, char[] a2)

public static void copyChars(char[] source, char[] destination)

함수 내부를 안보더라도, 메소드의 의도를 파악할 수 있다.

  • 아무런 정보를 제공하지 않는 Noise Word를 지양해라
    Product vs ProductInfo vs ProductData
    Name vs NameString
    getActiveAccount() vs getActiveAccounts() vs getActiveAccountInfo()
    moneyAmount vs money, theMessage vs message

발음하기 쉬운 이름을 사용해라

genymdhms(generate date, year, month, day, hour, minute, second) -> generationTimeStamp

검색하기 쉬운 이름을 사용해라

숫자, 문자 e와 같이 텍스트 코드에서 쉽게 눈에 띄지 않는 경우 문제점이 있다. string final static으로 따로 빼서 상수로 정의하고, 변수명으로 e와 같은 경우를 지양하고 의도를 들어내라.

인코딩을 피하라

멤버 변수 m_, 인터페이스 IinterfaceName 와 같은 인코딩은 불필요한 정신적 부담이며, 현대적인 IDE에서는 사용하지 않는다.

클래스 메소드 이름

클래스는 명사(구), 메소드는 동사(구)가 적합.

개념 하나에 단어 하나를 사용하라

똑같은 메소드를 클래스마다 fetch, retrieve, get 제각기 부르면 혼란스럽다.
마찬가지로 controller, manager, driver를 섞어 쓰면 혼란스럽다.

개발자에 친숙한 기술 개념을 사용하라.(ex.Queue), 그렇지 못한 경우, 문제 영역과 관련 있는 이름을 사용하라.

의미 있는 맥락을 추가하라

state만을 봤을 때, 주소의 일부를 확인하는 데 시간이 걸린다. addr접두어를 추가하거나, Address라는 클래스를 생성하여 위임하는 것도 좋은 방법이다.

그렇다고 모든 클래스의 이름을 GSD로 시작하겠다는 것도 바람직한 생각은 아니다. 추후에 IDE작업할 때, 나열되는 GSD들의 목록을 보게됬을 때의 빡침은 상상하기도 싫다.

후기

인트로 부분이라 쉽게 읽혔다. 우테코를 준비하면서, 고민을 많이했던 이름 짓기 부분인데, 그 때의 고민들의 명확한 기준들을 제시해준 것 같다. 앞으로의 책의 내용들이 더욱 기대된다.

profile
The Process

0개의 댓글