이번 포스팅에선 클린 코드 5장 - 형식 맞추기에 대해 알아보겠습니다.
왜 형식을 맞춰야 할까?
1장에서 우리는 저자라고 했습니다.
독자가 읽고 수정하기 편하도록 할 의무가 있습니다.
public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList();
for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell);return flaggedCells;}
위하고 아래 코드 둘 중 어떤 게 잘 읽히나요? 당연히 아래입니다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells
}
항상 동일한 형식의 코드를 짤 수 있게 하는 게 중요합니다.
팀 프로젝트면 팀원과 정한 형식
개인 프로젝트면 개인이 정한 형식
어떤 소스에선 a 형식으로, 어떤 소스에선 b 형식으로 짜게 되면 소스 읽는데 엄청 어려움이 생깁니다.
사람이 코드를 이해하는데 코드의 구조, 형식이 익숙할수록 도움이 된다고 합니다.
그럼 어떤 형식으로 짜야 좋을지 알아보겠습니다.
좋은 코드 형식 (세로)
1. 적절한 행 길이를 유지하라!
JUnit, testNG 등 큰 프로젝트들도 하나의 클래스가
대부분 200 줄을 넘지 않는다고 합니다. 제일 긴 파일은 400줄 정도?
그럼 여기서 알 수 있는 부분은 엄청 큰 프로젝트라도 하나의 클래스 파일 길이가 200줄 정도여도 충분히 개발 가능하다입니다.
클래스 길이가 길면 길수록 이해가 어렵기 때문에 짧게 짤려고 노력하자. (200줄 미만으로)
2. 신문 기사처럼 작성하라!
신문 기사를 보면 헤더 - 전체 요약문 - 본문이 나오듯이
소스 코드도 가장 중요하고 대표가 될만한 부분부터 위에서 차근차근 정리하자.
가장 대표가 될만한 소스 코드가 중간에 있으면 소스를 이해하는 게 정말 어렵다.
3. 개념은 빈 행으로 분리하라!
글에 문단이 있듯이 코드에는 빈 행이 있다.
아래 소스코드를 보면 다 따닥따닥 붙어있어서 잘 안 읽힌다.
엄청 간단한 소스인데 이정도다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
아래처럼 변수는 변수끼리 로직은 로직끼리 (로직 내에서도 다른 개념이면 빈 행으로!) 반환은 반환만 따로 구분해주니 아주 읽기가 편해졌다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList(); // 변수
for (Cell cell : gameBoard) // for 문
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells; // 반환
}
4. 세로 밀집도
개념을 빈행으로 구분했다면 세로 밀집도는 연관성을 의미한다!
아래 처럼 변수가 for문 로직 위에 붙어있다.
뭔가 보기 껄끄럽지 않나? 변수는 변수끼리 붙어있었으면 좋겠다는 생각이 든다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
List<Cell> dummyCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
dummyCells.add(cell);
return flaggedCells;
}
아래 코드처럼 변경하니 마음이 편해졌다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
List<Cell> dummyCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
dummyCells.add(cell);
return flaggedCells;
}
5. 코드 순서
클래스 내에 아래와 같은 순서로 코드를 작성하자.
1) static 변수 : public -> protected -> package -> private
2) instance 변수 : public -> protected -> package -> private
3) 생성자
4) 메서드 : (public -> private -> private) -> (public -> private -> private)...
public 메서드에서 호출되는 private 메서드는 바로 아래에 둔다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
addFlaggedCells(flaggedCells);
return flaggedCells;
}
private void addFlaggedCells(List<Cell> flaggedCells) {
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
}
좋은 코드 형식 (가로)
1. 가로 길이를 길게 하지말자!
가로 길이가 도대체 얼마가 긴 걸까?
인텔리제이를 켜서 클래스를 만들어보자
그럼 아래와 같이 선이 보이는데 저기까지 문자가 120글자가 들어갑니다.
120글자를 빽빽하게 항상 코드를 작성하라는 게 아니라 최대한 저기는 넘지 말자라는 의미입니다.
길면 길수록 이해가 안 가니 되도록이면 짧게 작성합시다.
2. 공백을 잘 넣자!
아래와 같이
=, : 양 옆에 공백이 없고
함수 호출 부분에 공백이 있고 예) cell .isFlagged()
보기가 어렵고 소스가 깔끔해 보이지 않는다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells=new ArrayList();
for (Cell cell:gameBoard)
if (cell .isFlagged())
flaggedCells .add(cell);
return flaggedCells;
}
공백을 잘 쓰자.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
3. 정렬을 하지 말아라!
가장 긴 변수랑 뭔가 맞춰볼려고 아래처럼 정렬을 한다면 그건 잘못된 생각이다.
아래처럼쓰면 어떤 값을 넣는지 솔직히 잘 안 보이고 변수명만 보인다.
context = context;
socket = s;
requestParsingTimeLimit = 10000;
아래와 같이 쓰자.
context = context;
socket = s;
requestParsingTimeLimit = 10000;
4. 들여쓰기를 잘하자!
아래처럼 들여쓰기를 안 하고 그냥 엔터만 치면서 코드를 짜면 보기가 불편하다.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells=new ArrayList();
for (Cell cell:gameBoard)
if (cell .isFlagged())
flaggedCells .add(cell);
return flaggedCells;
}
아래처럼 각 로직에 맞게 들여쓰기를 잘 쓰자!
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged()) // for문 안이니까 들여쓰기 +1
flaggedCells.add(cell); // if문 안이니까 들여쓰기 +2
return flaggedCells;
}
팀 코딩 컨벤션
위에 소개한 좋은 형식들도 중요하지만 가장 중요한 건 같이 일하는 팀원과 정한 코딩 컨벤션이다.
아래 유명한 컨벤션 가이드를 참고해서 팀원들과 잘 형식을 정해보자.
구글 java 컨벤션 : https://google.github.io/styleguide/javaguide.html
네이버 java 컨벤션 : https://naver.github.io/hackday-conventions-java/
개발자 나름 선호하는 코딩 컨벤션이 틀리기 때문에 위에 설명한 내용이 맘에 안 들 수 있습니다.
각자 열심히 개발하면서 보기 좋다고 생각되는 형식이 있기 때문이죠.
다른 사람들과 형식이 다르다면 너무 고집하지말고 같이 얘기하면서 뭐가 좋은지 잘 느껴보고 적용하는 게 중요합니다.
'Clean Code' 카테고리의 다른 글
[클린 코드] 7장 - 오류 처리 (Error Handling) (0) | 2022.03.07 |
---|---|
[클린 코드] 6장 - 객체와 자료 구조 (Objects and Data Structures) (0) | 2022.03.06 |
[클린 코드] 4장 - 주석 (Comments) (0) | 2022.03.01 |
[클린 코드] 3장 - 함수 (Functions) (0) | 2022.02.28 |
[클린 코드] 2장 - 의미 있는 이름 (Meaningful Names) (0) | 2022.02.27 |
댓글