클린 코드(Clean Code) - 5장 형식

Muzi·2023년 1월 11일
0

Clean Code

목록 보기
5/14

형식

프로그래머라면 형식을 깔끔하게 맞춰 코드를 짜야 한다

1. Why?

코드가 바뀌어도 구현 스타일과 가독성 수준은 유지보수 용이성과 확장성에 계속 영향을 미친다

2. 적절한 행 길이를 유지하라

7개의 자바 라이브러리를 조사한 결과 길이가 500줄을 넘지 않고, 대부분 200줄 정도인 파일로 구축되어 있다

신문 기사처럼 작성하라

  • 최상단엔 기사를 몇 마디로 요약하는 표제가 나온다. 첫 문단은 전체 기사 내용을 요약한다.
  • 소스파일도 신문 기사와 비슷하게 작성하자
  • 첫 부분은 고차원 개념과 알고리즘의 설명을, 아래로 내려갈수록 의도를 세세하게 묘사하자.
  • 마지막에는 가장 저차원 함수와 세부 내역이 나온다.
  • 이름은 간단하면서도 설명이 가능하게 짓는다

개념은 빈 행(줄 바꿈)으로 분리하라

  • 빈 행은 새로운 개념을 시작한다는 단서
  • 개념을 분리해주는 역할을 한다

// 빈 행을 넣지 않을 경우
package fitnesse.wikitext.widgets;
import java.util.regex.*;
public class BoldWidget extends ParentWidget {
  public static final String REGEXP = "'''.+?'''";
  private static final Pattern pattern = Pattern.compile("'''(.+?)'''",
  Pattern.MULTILINE + Pattern.DOTALL);
  public BoldWidget(ParentWidget parent, String text) throws Exception {
    super(parent);
    Matcher match = pattern.matcher(text); match.find();
    addChildWidgets(match.group(1));}
  public String render() throws Exception {
    StringBuffer html = new StringBuffer("<b>");         
    html.append(childHtml()).append("</b>");
    return html.toString();
  }
}

// 빈 행을 넣을 경우
package fitnesse.wikitext.widgets;

import java.util.regex.*;

public class BoldWidget extends ParentWidget {
  public static final String REGEXP = "'''.+?'''";
  private static final Pattern pattern = Pattern.compile("'''(.+?)'''",
    Pattern.MULTILINE + Pattern.DOTALL
  );

  public BoldWidget(ParentWidget parent, String text) throws Exception {
    super(parent);
    Matcher match = pattern.matcher(text);
    match.find();
    addChildWidgets(match.group(1));
  }

  public String render() throws Exception {
    StringBuffer html = new StringBuffer("<b>");
    html.append(childHtml()).append("</b>");
    return html.toString();
  }
}

세로 밀집도

  • 줄 바꿈이 개념을 분리한다면 세로 밀집도는 연관성을 의미한다
  • 즉, 서로 밀집한 코드 행은 세로로 가까이 놓아야 한다는 뜻

// 의미 없는 주석으로 두 인스턴스 변수를 떨어져있는 경우
public class ReporterConfig {
  /**
   * 의미 없는 주석 1
   */
  private String m_className;
  
  /**
   * 의미 없는 주석 2
   */
  private List<Property> m_properties = new ArrayList<Property>();
  public void addProperty(Property property) {
    m_properties.add(property);
  }
}

// 의미 없는 주석을 제거
public class ReporterConfig {
  private String m_className;
  private List<Property> m_properties = new ArrayList<Property>();
  
  public void addProperty(Property property) {
    m_properties.add(property);
  }

수직 거리

연관성이 깊을수록 세로로 가까이 둬야 한다
시스템이 무엇을 하는지 이해하고 싶은데, 이 조각 저 조각 어디에 있는지 찾고 기억하느라 시간과 노력을 소모하지 말자

  • 변수 선언 : 변수는 사용하는 위치에 최대한 가까이 선언
    • 루프를 제어하는 변수는 흔히 루프 문 내부에 선언
  • 인스턴스 변수 : 변수 간에 서로 거리를 두지 않는다
    • c++ : 클래스 마지막에 선언 / java : 클래스 맨 처음에 선언
    • 모두가 잘 알고 있는 잘 알려진 위치에 인스턴스 변수를 선언
  • 종속 함수 : 한 함수가 다른 함수를 호출한다면 두 함수는 세로로 가까이 배치

세로 순서

호출 되는 함수를 호출하는 함수보다 나중에 배치한다

3. 가로 형식 맞추기

프로그래머는 명백하게 짧은 행을 선호한다. 그러므로 짧은 행이 바람직하다

가로 공백과 밀집도

  • 가로 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한다
private void measureLine(String line) {
  lineCount++;
  int lineSize = line.length(); // 할당 연산자를 강조하기위해 앞뒤에 공백을 준다
  totalChars += lineSize;
  lineWithHistogram.addLine(lineSize, lineCount);
  recordWidestLine(lineSize);
}

가로 정렬

// 코드의 엉뚱한 부분을 강조해 진짜 의도가 가려진다
// 선언문과 할당문을 굳이 별도로 정리할 필요가 없다
public class FitNesseExpediter implements ResponseSender {
  private     Socket          socket;
  private     InputStream     input;
  private     OutputStream    output;
  private     Reques          request;         
  private     Response        response;    
  private     FitNesseContex  context;
  protected   long            requestParsingTimeLimit;
  private     long            requestProgress;
  private     long            requestParsingDeadline;
  private     boolean         hasError;
  ...
}

// after
public class FitNesseExpediter implements ResponseSender {
  private Socket socket;
  private InputStream input;
  private OutputStream output;
  private Reques request;         
  private Response response;    
  private FitNesseContex context;
  protected long requestParsingTimeLimit;
  private long requestProgress;
  private long requestParsingDeadline;
  private boolean hasError;
  ...
}

마치며

팀으로 하는 프로젝트일수록 가독성과 유지보수를 생각하며 팀 규칙인 코드 형식을 지키는건 중요하다. 내 코드를 읽는 다른사람을 생각하며...

profile
좋아하는걸 열심히

0개의 댓글