[체크리스트] 컨벤션(자바, 깃, 등등)
Intro
우테코 프리코스 4주간
겪은 경험을 바탕으로 “코딩 컨벤션(Coding Convention)”을 정리
- 구글 자바 컨벤션
- 깃 컨벤션
- 우테코 프리코스 등등…
CHECK LIST
깃 커밋 컨벤션
- feat (feature)
- ex)
git commit -m "feat: xxx 기능 구현"
- ex)
- fix (bug fix)
- docs (documentation)
- 예로 README.md 작성
- style (formatting, missing semi colons, …)
- refactor
- 리팩토링 - Production Code 변경
- test (when adding missing tests)
- chore (maintain)
- 유지보수 관련 빌드, 패키지 매니저 등 설정 - Production Code 변경X
구글 자바 컨벤션
-
참고 문서 : 자세한것은 이곳에서, 자동 적용법
-
- Ctrl+Alt+L(자동 정렬) / Ctrl+Alt+I(임포트 정리)
-
파일 코드 구조 : 라이센스(저작권) -> 패키지 구문 -> 임포트 구문 -> 하나의 최상위 클래스
-
와일드 카드(=*) 임포트 사용X :
import java.io.*
-
열제한 : 100 / 들여쓰기 : +2 / 줄바꿈 들여쓰기 : +4
-
K & R 스타일(=Kernighan & Ritchie)
return new MyClass() { @Override public void method() { if (condition()) { try { something(); } catch (ProblemException e) { recover(); } } else if (otherCondition()) { somethingElse(); } else { lastThing(); } } }; void doNothingElse() { // 권장 } private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS } // enum은 허용
-
C스타일 배열 선언문 금지
String[] args
OK-
String args[]
NO
-
주석 예시
/* * This is // And so /* Or you can * okay. // is this. * even do this. */ */
-
long의 값을 가지는 정수 리터럴은 대문자 L :
3000l
대신3000L
사용- l과 1의 햇갈림을 방지
-
식별자 룰 - 패키지, 클래스, 함수, 상수 제외하고는 전부 유사
-
패키지 이름 전부 소문자(언더스코어 없음) :
com.example.deepspace
-
클래스 이름은 UpperCamelCase(=Pascal Case) :
CharacterItem
주로 “명사, 명사구” -
함수 이름은 lowerCamelCase :
sendMessage
주로 “동사, 동사구” -
상수 이름은
CONSTANT_CASE
주로 “명사, 명사구” - 필드 이름은 lowerCamelCase :
computedValues
주로 “명사, 명사구” - 파라미터 이름은 lowerCamelCase : 메서드 이름과 유사한건 피해주기
- 지역변수 이름은 lowerCamelCase
-
패키지 이름 전부 소문자(언더스코어 없음) :
-
참고) 우테코 컨벤션 특징
- 블럭 들여쓰기 기본 4칸(스페이스4)
- 줄바꿈 들여쓰기 기본 8칸(스페이스8)
- 문자 유니코드, 열제한 120
프리코스 과정 중 컨벤션
- 깃 관리할 필요 없는 파일들이 존재
-
.class
파일은 java코드로 생성되어서 관리할 필요 X -
.idea
폴더는 IntelliJ IDEA 가 자동 생성하므로 관리할 필요 X -
.gitignore
확인해보면 “out/, .idea” 선언 확인
-
-
서비스 구현을 요청받았을때 해결 과정
- README.md 작성 : 요구사항 분석 -> 기능 목록 <-> 구현
- 비지니스, UI 로직 분리는 기본
- 참고) 프리코스 3주차 README.md 내용을 아래에서 확인
-
기능 목록을 처음부터 상세히 작성할 필요X -> 오히려 구현하면서 수정해주자(+예외처리)
-
값을 “하드 코딩 X” -> 상수(static final) 권장!
-
변수 이름에 자료형 사용X
- 하나의 함수는 하나의 기능!! + 함수 길이 15라인 이내로 분리 연습!!
- main 함수도 포함
-
테스트는 “작은 단위 테스트” 부터 진행!
-
3항 연산자는 사용X -> 가독성이 떨어지기 때문!
-
else 사용X 연습!! -> 부정문 등등 여러 방법으로 조건문 생각하길
-
연관성 있는 상수는 Java Enum 사용 -> static final 대신 enum 연습!!
-
값의 변경을 막을 변수들은 꼭 final 키워드 사용!!
-
인스턴스 변수의 접근 제어자는 private으로 구현(항상 하는거긴 함)
-
객체는 객체스럽게 사용! -> getter만 하지말고 “가능한 비지니스 로직”은 작성권장(=도메인 모델 패턴)
-
불 필요한 필드(인스턴스 변수)는 제거
-
테스트를 위한 코드는 구현 코드에서 구현하지 말자
- 테스트를 위해 접근 제어자를 바꾸는 경우
- 테스트 코드에서만 사용되는 메서드
-
private 함수를 테스트 하고 싶다면 클래스(객체) 분리를 고려
- 가독성의 이유만으로 분리한 private 함수의 경우 public 함수로 검증 가능하다고 여겨질 수 있다. (public 함수가 private 함수를 사용하고 있는 경우 테스트 범위에 포함됨)
- 하지만 가독성 이상의 역할을 하는 경우, 테스트하기 쉽게 구현하기 위해서는 해당 역할을 수행하는 다른 객체를 만들 타이밍이 아닐지 고민해 볼 수 있다.
- 따라서 너무 많은 역할을 하고 있는 함수나 객체를 어떻게 의미 있는 단위로 분할할지에 초점을 맞춰 볼 필요가 있다.
-
리소스 정리(close) 는 필수고 “역순”으로 할 것
- try - with - resource AutoCloseable 기능 활용도 좋다. 여러개는 세미콜론(;)로 구분
- 주의점: 자동 반환이니까 원하지 않는 경우에도 닫힐 수 있다.
/** * 회원가입 -> try - resource 패턴으로 자원 자동 반환 */ public User save(User user) { try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); mapper.saveUser(user); session.commit(); //트랜잭션 commit return user; //생성된 generatedKeys 포함 } }
Enum 추가 정리 - 자주 사용해보자!
예시 코드
// enum 도 객체!
public enum Menu {
양송이수프(6000, "애피타이저"), 타파스(5500, "애피타이저"), 시저샐러드(8000, "애피타이저"),
티본스테이크(55000, "메인"), 바비큐립(54000, "메인"), 해산물파스타(35000, "메인"), 크리스마스파스타(25000, "메인"),
초코케이크(15000, "디저트"), 아이스크림(5000, "디저트"),
제로콜라(3000, "음료"), 레드와인(60000, "음료"), 샴페인(25000, "음료");
private final int price;
private final String type;
Menu(int price, String type) {
this.price = price;
this.type = type;
}
public int getPrice() {
return this.price;
}
public String getType() {
return this.type;
}
}
public enum Direction { EAST, SOUTH, WEST, NORTH } // 값 : 0, 1, 2, 3 가짐 (참고용 TEST)
출력 테스트
System.out.println(Menu.valueOf("샴페인")); // 샴페인
System.out.println(Menu.샴페인); // 샴페인
System.out.println(Menu.샴페인.getType()); // 음료
System.out.println(Menu.샴페인.getPrice()); // 25000
System.out.println(Menu.샴페인.name()); // 샴페인
System.out.println(Menu.샴페인.ordinal()); // 11 -> 11번째 순서의미
for(Direction dir : Direction.values()) { // 배열로 반환하는 메소드
System.out.println(dir.compareTo(Direction.WEST)); // -2 -1 0 1
}
기본 제공 메소드
-
Menu.샴페인
처럼 바로 해당 Enum 객체에 접근도 가능하며, -
Enum에서 제공하는
valueOf
메소드를 통해서 “String” 으로도 접근 가능 -
name() : 이름반환
-
ordinal() : 순서 반환
-
values() : 배열로 Enum 객체 전부 반환
-2 -1 0 1
의 의미는?
- compareTo 특징과 Enum 특징 때문
public enum Direction { EAST, SOUTH, WEST, NORTH } // 값 0, 1, 2, 3 가짐
- compareTo 는 두 값을 뺀 결과가 나옴
- 음수면 “왼쪽”
- 양수면 “오른쪽”
- 0이면 “동일”
- 계산 과정
- 0 - 2 = -2
- 1 - 2 = -1
- 2 - 2 = 0
- 3 - 2 = 1
프리코스 3주차 기능구현 과정
과제이름 로또 - 기능 목록 작성 후 규칙에 맞춰서 구현
기능 목록
1. 입력 기능
-
로또 구입 금액을 입력 - InputLotto#purchaseMoney(), readMoney()
- 사용자가 잘못된 값을 입력하면 예외 발생 - IllegalArgumentException
-
당첨 번호를 입력 - InputLotto#answerNumber(), readAnswer()
- 사용자가 잘못된 값을 입력하면 예외 발생 - IllegalArgumentException
- 숫자 범위 예외 처리용 함수 - InputLotto#exceptNumberRange()
-
보너스 번호를 입력 - InputLotto#bonusNumber(), readBonus()
- 사용자가 잘못된 값을 입력하면 예외 발생 - IllegalArgumentException
- 숫자 범위 예외 처리용 함수 - InputLotto#exceptNumberRange()
2. 로또 기능
-
1개의 로또 발행 - LottoGenerator#createLotto()
- X개의 로또 기록 - LottoGenerator#createLottos()
-
사용자 로또 번호와 당첨 번호 비교 - Referee#compareToLottos(), compareToLotto()
- 수익률 계산 - Referee#calculateIncome()
- 기존 로또 클래스에 getter 추가 - Lotto#getNumbers()
3. 출력 기능
- 로또 수량 출력 - OutputLotto#counts()
- 로또 번호 출력(오름차순) - OutputLotto#numbers()
- 당첨 내역 출력 - OutputLotto#winningHistory()
- 수익률 출력 - OutputLotto#incomeRate()
4. 추가 예외 처리
- 숫자 범위 예외 처리용 함수 - InputLotto#exceptNumberRange()
- 로또 숫자 중복 검증 함수 - Lotto#validateDuplication()
요구사항 분석
1. 입출력 요구 사항
1-1. 입력
-
로또 구입 금액 입력
- 구입 금액은 1000원 단위
- 1000원으로 나누어 떨어지지 않으면 예외 처리
-
당첨 번호를 입력
- 번호는 쉼표(,)를 기준으로 구분
- 보너스 번호를 입력
1-2. 출력
-
로또 수량과 번호를 출력
- 번호는 오름차순 정렬
-
당첨 내역을 출력
- 쉼표(,)로 1,000원 단위 구분 :
3개 일치 (5,000원) - 1개
- 보너스 볼 일치할 경우 :
5개 일치, 보너스 볼 일치 (30,000,000원) - 0개
- 쉼표(,)로 1,000원 단위 구분 :
-
수익률을 출력
- 소수점 둘째 자리에서 반올림 :
총 수익률은 62.5%입니다.
- 소수점 둘째 자리에서 반올림 :
-
예외 상황 에러 문구 출력
- “[ERROR]” 로 시작 :
[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.
- “[ERROR]” 로 시작 :
2. 로또 기능 분석
-
1개의 로또 발행
- 중복되지 않는 6개의 숫자
- 범위 : 1~45
- 가격 : 1000원
-
사용자 로또 번호와 당첨 번호를 비교
- 당첨 내역
- 수익률
- 잘못된 값 입력시
IllegalArgumentException
에러 발생 후 다시 입력 받기- “[ERROR]” 로 시작하는 에러메시지 출력 필수
3. 테스트 예제
-
입력
구입금액을 입력해 주세요.
- 로또 구입 금액 :
14000
- 14000 / 1000 을 통해 14개의 로또가 발행되어야 함
- 만약 14001 이라면? 예외 발생
- 담청 번호 :
1,2,3,4,5,6
- 보너스 번호 :
7
-
출력
-
구매수량 출력 :
8개를 구매했습니다.
-
로또 번호 출력(오름차순)
[8, 21, 23, 41, 42, 43]
[3, 5, 11, 16, 32, 38]
- 등등… 8개..
-
당첨 내역을 출력
3개 일치 (5,000원) - 1개
4개 일치 (50,000원) - 0개
5개 일치 (1,500,000원) - 0개
5개 일치, 보너스 볼 일치 (30,000,000원) - 0개
6개 일치 (2,000,000,000원) - 0개
-
수익률 출력(소수점 둘째 자리 반올림) :
총 수익률은 62.5%입니다.
-
예외 상황 :
[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.
-
댓글남기기