본문 바로가기
Programming/Java, Spring

자바 코딩 컨벤션 - 우아한테크코스 우테코 클린코드 #1

by Renechoi 2022. 10. 30.

우아한테크코스에서 클린코드로 요구되는 사항들을 살펴본다. 

 

본 포스팅은 네이버 캠퍼스 핵데이에서 제공하는 코딩 컨벤션 문서의 내용과 그에 대한 코멘트를 적어본다. 

 

https://naver.github.io/hackday-conventions-java/

 

캠퍼스 핵데이 Java 코딩 컨벤션

중괄호({,}) 는 클래스, 메서드, 제어문의 블럭을 구분한다. 5.1. K&R 스타일로 중괄호 선언 클래스 선언, 메서드 선언, 조건/반복문 등의 코드 블럭을 감싸는 중괄호에 적용되는 규칙이다. 중괄호

naver.github.io

 


1. 파일 공통 요건 

 

1.1 파일 인코딩은 UTF-8 

 

1.2 새줄 문자는 LF 

Unix 형식의 새줄 문자인 LF를 사용한다. Windows 형식인 CRLF가 섞이지 않도록 편집기와 GIT 설정 등을 확인한다. 
Git을 쓴다면 .gitattributes 파일 안에 정책을 선언해서 지정된 새줄 문자로 강제 변환하거나 예외가 될 확장자를 지정할 수 있다. 
아래는 그 예시이다. 

 

 

 

*.c text eol=lf
*.cpp text eol=lf
*.h text eol=lf

# exception for visual studio project configuration
*.sln text eol=crlf
*.vs text eol=crlf
*.csproj eol=crlf
*.props eol=crlf
*.filters eol=crlf

 

줄 바꿈 문자에 대한 이야기인데 

현재의 세팅을 보았을 때 비쥬얼 스튜디오의 경우 LF, 인텔리J의 경우 CRLF가 기본 설정으로 되어 있는 것을 확인했다. 

 

 

 

MDN 공식 문서에서 제공하는 LF와 CRLF에 대한 설명은 다음과 같다. 

 

https://developer.mozilla.org/en-US/docs/Glossary/CRLF

 

CRLF - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

CR and LF are control characters or bytecode that can be used to mark a line break in a text file.

developer.mozilla.org

 

 

줄 바꾸는 규칙에 있어서 CRLF는 (\r\n)을 LF는 (\n)인 것으로 이해하면 쉽다. 

 

Intellij에서 이미 작성한 문서를 LF로 변경하도록 하는 방법은 무엇일까? 

 

간단하다. 해당 문서가 열린 상태에서 오른쪽 밑에서 변경해주면 된다. 

 

 

 

깃에서 라인 코딩을 설정해줄 수 있다. 

 

core.eol = native. OS 기본 설정을 따르도록 한다 /  Windwos CRLF, Linux LF
core.eol = crlf CRLF 를 사용한다
core.eol = lf LF를 사용한다

## 설정
$  git config --global core.eol lf
 
## 설정 확인
$ git config --list

 

또 다른 명령어로 autocrlf 명령어가 있다.

 

윈도우에서 autocrlf를 true로 설정하면 commit과 push시 원격 저장소에 자동으로 LF 변경이 되고 

checkout 할시 CRLF로 다시 변경이 되는 기능이다. 

 

git config --global core.autocrlf true

 

맥, Linux에서는 반대로 받아올 때 자동으로 변환되도록 하는 설정은 다음과 같다 

 

git config --global core.autocrlf input

 

 

 

 

1.3 파일의 마지막에는 새줄 

 

파일의 마지막은 새줄 문자 LF로 끝나야 한다. 

 

즉, 파일의 마지막은 항상 개행 문자 (= 줄바꿈 문자)로 끝나야 한다는 것이다. 

 

IDE (인텔리J)의 setting에서 설정해줄 수 있다. 

 

 

마지막으로 파일의 현재 설정이 실제로 어떻게 되어 있는지를 윈도우에서 다음 명령어를 통해 확인할 수 있다! 

 

(Get-Content 'woowacourse\java-onboarding\src\main\java\onboarding\Problem1.java' -Raw) -match "\r\n$"

 

False가 나온다면 LF 설정

 

 

 

 

 

2. 이름 

 

2.1 식별자에는 영문/숫자/언더스코어만 허용 

변수명, 클래스명, 메서드명 등에는 영어와 숫자만을 사용한다.
상수에는 단어 사이의 구분을 위하여 언더스코어(_)를 사용한다.
정규표현식 '[^A-Za-z0-9_]'에 부합해야 한다.

 

2.2 한국어 발음대로의 표기 금지 

 

 

단 고유명사는 예외이다. 

 

 

 

2.3 대문자로 표기할 약어 명시 

 

 

클래스명, 변수명에 쓰일 단어 중 모든 글자를 대문자로 표기할 약어의 목록을 프로젝트별로 명시적으로 정의한다.

프로젝트 내에서 정의한 단어 목록이 없다면 'XmlRpcHttpApiUrl'과 같이 쓴다. 

 

예를 들어 HTTP + API + URL을 보면, 

 

기본 : HttpApiUrl 

API를 정의했을 경우 : HttpAPIUrl

전부 정의했을 경우 : HTTPAPIURL 

 

 

 

2.4 패키지 이름은 소문자로 구성 

 

패키지 이름은 소문자를 사용하여 작성한다. 언더스코어나 대문자를 섞지 않는다.

ex) onborading

 

 

2.5 클래스/인터페이스 이름에 대문자 카멜표기법 적용

 

클래스 이름은 카멜표기법을 쓴다. 

ex) AccessToken 

 

 

2.6 클래스 이름에 명사 사용

 

 

2.7 인터페이스 이름에 명사/형용사 사용

 

ex) AutoClosable 

 

 

2.8 테스트 클래스는 'Test'로 끝남 

 

 

2.9 메서드 이름에 소문자 카멜표기법 적용 

 

2.10 메서드 이름은 동사/전치사로 시작 

 

ex) renderHtml() , toString()

 

 

2.11 상수는 대문자와 언더스코어로 구성 

 

상태를 가지지 않는 자료형이면서 static final로 선언되어 있는 필드일 때를 상수로 간주한다.
상수는 대문자로 작성하며, 복합어는 언더스코어를 사용하여 구분한다. 

 

 

ex ) 

public final int UNLIMITED = -1;
public final String POSTAL_CODE_EXPRESSION = “POST”;

 

 

2.12 변수에 소문자 카멜표기법 적용 

 

ex) 

private boolean authorized;
private int accessToken;

 

 

2.13 임시 변수 외에는 1글자 이름 사용 금지 

 

 

 

다시 보니 변수명을 대문자로 쓴 경우도 있었다.

분명 알고 있다고 생각했지만 이와 같이 나도 모르게 써버린 상황들이 있다.

 

 

 

3. 선언 

 

 

3.1 소스파일당 1개의 탑레벨 클래스를 담기 

 

굳이 한 파일 안에 선언해야 한다면 내부 클래스로 선언 

 

3.2 static import에만 와일드 카드 허용 

 

나쁜 예 
import java.util.*;

좋은 예 
import java.util.List;
import java.util.ArrayList;

 

 

 

3.3 제한자 선언의 순서 

 

public protected private abstract static final transient volatile synchronized native strictfp

 

 

3.4 애너테이션 선언 후 새줄 사용 

 

@RequestMapping("/guests")
public void findGuests() {}

 

 

3.5 한 줄에 한 문장 

 

3.6 하나의 선언문에는 하나의 변수만 

 

3.7 배열에서 대괄호는 타입 뒤에 선언 

나쁜 예 

String names[];

좋은 예 

String[] names;

 

 

3.8 'long'형 값의 마지막에 'L' 붙이기 

 

3.9 특수 문자의 전용 선언 방식을 활용 

 

\b, \f, \n, \r, \t, '\", \\ 와 같이 특별히 정의된 선번 방식의 특수 문자들은
숫자를 이용한 방식보다 전용 방식을 활용한다. 

 

System.out.println("---\n---");

 

 

 

4. 들여쓰기 

 

4.1 하드탭 사용

 

4.2 탭의 크기는 4개의 스페이스 

 

4.3 블럭 들여쓰기 

 

 

 

5. 중괄호 

 

 

5.1 K&R 스타일로 중괄호 선언 

 

Kernighan and Ritchie style을 따른다.
줄의 마지막에서 시작 중괄호 '{'를 쓰고 열고 새줄을 삽입한다.
블럭을 마친후에는 새줄 삽입 후 중괄호를 닫는다. 

 

public class SearchConditionParser {
    public boolean isValidExpression(String exp) {

        if (exp == null) {
            return false;
        }

        for (char ch : exp.toCharArray()) {
            ....
        }

        return true;
    }
}

 

5.2 닫는 중괄호와 같은 줄에 else, catch, finally, while 선언 

 

 

 

if (line.startWith(WARNING_PREFIX)) {
    return LogPattern.WARN;
} else if (line.startWith(DANGER_PREFIX)) {
    return LogPattern.NORMAL;
} else {
    return LogPattern.NORMAL;
}

 

try {
    writeLog();
} catch (IOException ioe) {
    reportFailure(ioe);
} finally {
    writeFooter();
}

 

do {
    write(line);
    line = readLine();
} while (line != null);

 

 

 

5.3 빈 블럭에 새줄 없이 중괄호 닫기 허용 

 

public void close() {}

 

 

 

5.4 조건/반복문에 중괄호 필수 사용 

 

조건, 반복문이 한 줄로 끝나더라도 중괄호를 활용한다.
전후의 공백, 제어문 앞 뒤의 새줄 규칙도 함께 고려한다. 

 

if (exp == null) {
    return false;
}

for (char ch : exp.toCharArray()) {

    if (ch == 0) {
        return false;
    }

}

 

 

 

6. 줄바꿈 

 

6.1 최대 줄 너비는 120

 

6.2 package, import 선언문은 한 줄로 

 

6.3 줄바꿈 후 추가 들여쓰기 

 

줄바꿈 이후 이어지는 줄에서는 최초 시작한 줄에서보다 적어도 1단계의 들여쓰기를 추가한다. 

 

 

6.4 줄바꿈 허용 위치 

 

가독성을 위해 줄을 바꾸는 위치는 다음 중의 하나로 한다. 

extends 선언 후 
implements 선언 후 
throws 선언 후 
시작 소괄호 ( ( ) 선언 후 
콤마 ( , ) 선언 후
. 전 
연산자 전 

 

public boolen isAbnormalAccess (
    User user, AccessLog log) {

    String message = user.getId() + "|" | log.getPrefix()
        + "|" + SUFFIX;
}

 

 

 

7. 빈 줄 

 

7.1 package 선언 후 빈 줄 삽입 

 

7.2 import 선언의 순서와 빈 줄 삽입 

 

예를 들어 다음과 같다. 

 

import java.util.Date;
import java.util.List;

import javax.naming.NamingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import com.google.common.base.Function;

import com.naver.lucy.util.AnnotationUtils;

 

7.3 메서드 사이에 빈 줄 삽입 

 

메서드의 선언이 끝난 후 다음 메서드 선언이 시작되기 전에 빈줄을 삽입한다. 

 

8. 공백 

 

8.1 공백으로 줄을 끝내지 않음 

 

8.2 대괄호 뒤에 공백 삽입 

 

int[] masks = new int[] {0, 1, 1};

 

 

8.3 중괄호의 시작 전, 종료 후에 공백 삽입 

 

여는 중괄호 앞에는 공백을 삽입한다.
닫는 중괄호 뒤에 else, catch 등의 키워드가 있을 경우 중괄호와 키워드 사이에 공백을 삽입한다. 

 

 

8.4 제어문 키워드와 여는 소괄호 사이에 공백 삽입 

 

if, for, while, catch, synchronized, switch와 같은 제어문 키워드의 뒤에 소괄호를 선언하는 경우
시작 소괄호 앞에 공백을 삽입한다. 

 

 

8.5 식별자와 여는 소괄호 사이에 공백 미삽입

 

식별자와 여는 소괄호 사이에는 공백을 삽입하지 않는다.
생성자와 메서드의 선언, 호출, 애너테이션 선언 뒤에 쓰이는 소괄호가 그에 해당한다. 

 

public StringProcessor() {} // 생성자

@Cached("local")
public String removeEndingDot(String original) {
    assertNotNull(original);
    ...
}

 

 

8.6 타입 캐스팅에 쓰이는 소괄호 내부 공백 미삽입 

 

String message = (String)rawLine;

 

8.7 제네릭스 산괄호의 공백 규칙 

 

제네릭스 선언에 쓰이는 산괄호(<>) 주위의 공백은 다음과 같이 처리한다. 
- 제네릭스 메서드 선언일 때만 < 앞에 공백을 삽입한다.
- < 뒤에 공백을 삽입하지 않는다.
- > 앞에 공백을 삽입하지 않는다. 
- 아래의 경우를 제외하고는 > 뒤에 공백을 삽입한다. 
1) 메서드 레퍼런스가 바로 이어질 때
2) 여는 소괄호가 바로 이어질 때
3) 메서드 이름이 바로 이어질 때 

 

public static <A extends Annotation> A find(AnnotatedElement elem, Class<A> type) { // 제네릭스 메서드 선언
    List<Integer> l1 = new ArrayList<>(); // '(' 가 바로 이어질때
    List<String> l2 = ImmutableList.Builder<String>::new; // 메서드 레퍼런스가 바로 이어질 때
    int diff = Util.<Integer, String>compare(l1, l2); // 메서드 이름이 바로 이어질 때
}

 

 

8.8 콤마/구분자 세미콜론의 뒤에만 공백 삽입 

 

for (int i = 0; i < length; i++) {
    display(level, message, i)
}

 

 

8.9 콜론의 앞 뒤에 공백 삽입 

 

반복문과 삼항연산자에서 콜론의 앞 뒤에는 공백을 삽입.
라벨 선언 뒤에는 아무런 문자열이 없으므로 앞에만 공백을 삽입. 

 

for (Customer customer : visitedCustomers) {
    AccessPattern pattern = isAbnormal(accessLog) ? AccessPattern.ABUSE : AccessPattern.NORMAL;
    int grade = evaluate(customer, pattern);

    switch (grade) {
        case GOLD :
            sendSms(customer);
        case SILVER :
            sendEmail(customer);
        default :
            inreasePoint(customer)
    }
}

 

 

8.10 이항/삼항 연산자의 앞 뒤에 공백 삽입 

 

if (pattern == Access.ABNORMAL) {
    return 0;
}

finalScore += weight * rawScore - absentCount;

if (finalScore > MAX_LIMIT) {
    return MAX_LIMIT;
}

 

 

 

8. 11 단항 연산자와 연산 대상 사이에 공백을 미삽입 

int point = score[++index] * rank-- * -1;

 

8.12 주석문 기호 전후의 공백 삽입 

/*
 * 공백 후 주석내용 시작
 */

System.out.print(true); // 주석 기호 앞 뒤로 공백

/* 주석내용 앞에 공백, 뒤에도 공백 */

 

 

 

Appendix A : editorconfig 파일 설정 

 

다양한 에디터와 IDE에서 공통적으로 지원하는 코드 스타일 설정 

 

# top-most EditorConfig file
root = true

[*]
# [encoding-utf8]
charset = utf-8

# [newline-lf]
end_of_line = lf

# [newline-eof]
insert_final_newline = true

[*.bat]
end_of_line = crlf

[*.java]
# [indentation-tab]
indent_style = tab

# [4-spaces-tab]
indent_size = 4
tab_width = 4

# [no-trailing-spaces]
trim_trailing_whitespace = true

[line-length-120]
max_line_length = 120

 

참고 부록 : Intellij 설정 

 

D.2 IntelliJ 

 

D.2.1 Formatter 적용 

 

 

 

 

D.2.2 수동 설정 방법 

 

D.2.2.1 들여쓰기 

  • File > Settings > Editor > Code Style > Java 메뉴로 이동
    • User tab charactor : 선택
    • Tab Size, Indent : 4

 

 

D.2.2.2 Import 구문 

 

File > Settings > Editors > Code Style > Java > Imports > Import Layout
로 이동해서 아래 항목을 설정한다.

 

  • General
    • Use single class import : 체크
    • Class count to use import with '*' : 99
    • Names count to use static import with '*' : 1
  • Import Layout

 

 

 

 

 

 

D.2.2.2 줄바꿈 시 연산자 위치 

 

  1. File > Settings > Editors > Code Style > Java > Wrapping and Braces 로 이동한다.
  2. Binary expressions 아래의 Operation sign on next line 항목을 선택한다.

 

 

 

 

D.2.3 파일의 마지막에 새줄 문자가 없는 경우 추가 

 

File > Settings > Editor > General 메뉴에서 Ensure line feed at file end on Save를 선택한다.

 

D.2.4 파일을 저장할 때마다 포맷터 자동 적용 

  1. File > Settings ( Ctrl + Alt + S ) > Plugins 메뉴로 이동
  2. Marketplace 탭에서 'Save Actions' 로 검색
  3. Save Actions' plugin의 상세 설명 화면에서 `[Install] 버튼 클릭
  4. IntelliJ를 재시작
  5. File > Settings > Other Settions > Save Actions 메뉴로 이동
  6. 아래 항목을 체크
    • Activate save actions on save
    • Optimize imoprts
    • Refomat file

 

 

D.2.5 일괄 변환 

 

프로젝트의 홈디렉토리에 커서를 놓은 채로 아래 메뉴를 실행하면 포르젝트의 모든 소스에 해당 설정을 일괄 적용한다. 

 

  • File > Line Separators
  • Code > Reformat Code
  • Code > Auto-Indent Lines
  • Code > Optimize Imports

 

 

 

D.2.6 CheckStyle 설정 

 

플러그인 및 검사 설치 

자세한 내용은 여기를 참고

 

 

 

D.2.7 공백 문자 보이기 설정 

 

탭과 스페이스가 섞여 있는 프로젝트의 코드를 정리할 때는 탭과 스페이스를 눈에 보이게 표시한다. 
File > Settings > Editor > General > Appearance`에서 `Show whitespaces`를 선택한다. 하위 분류에서 `Leading, Inner, Trailing
 을 선택한다.

 

D.2.8 커스터마이징

 

들여쓰기에 탭 대신 스페이스 사용

  1. File > Settings > Editor > Code Style > Java 메뉴로 이동한다.
  2. Tabs and Indents 탭으로 이동해서 아래 항목을 입력한다.
    • Use tab charactor : 미선택
    • Tab size : 4

 

줄바꿈 후 추가 들여쓰기 단계 조정

  1. File > Settings > Editor > Code Style > Java 메뉴로 이동한다.
  2. Tabs and Indents 탭으로 이동한다.
  3. Continuation ident: 항목을 8로 입력한다.
 
반응형