이번 장의 내용은 이 책을 보지 않았어도 여러분이 이미 대충은 알고 있었을 것이고, 이미 잘 지키고 있는 분들도 많을 것이다. 코드를 짤때 일정한 형식을 맞추는 것에대한 내용이다.
코드 글자를 구성하는 세세한 부분부터, 필드, 메서드의 배치까지 더 나은 방법을 제시한다.
형식(포맷팅)을 맞추는 목적
한가지를 분명히 짚고 넘어가자. 코드 형식은 중요하다! 너무 중요해서 무시하기 어렵다.
처음으로 코드를 짜고, 오랜 시간이 지나 원래 코드의 흔적을 더이상 찾아보기 어려울 정도로 코드가 바뀌어도
맨 처음 잡아놓은 구현 스타일과 가독성 수준은 유지보수의 용이성과, 확장성에 계속 영향을 미치게 된다.
즉, 오늘 처음구현한 코드의 가독성은 앞으로 바뀔 코드의 퀄리티에 지대한 영향을 미친다.
쉬운 예제를 하나 가져왔다.
1. 포맷팅을 맞추지 않은 버전
System.out.println("1부터 10까지의 합");
int sum=0;
for(int i=1;i<=10;i++)sum += i;
System.out.println("sum : "+sum);
System.out.println("avg : "+(double)sum/10);
System.out.println("프로그램 종료");
2. 포맷팅을 잘 맞춘 버전
System.out.println("1부터 10까지의 합");
int sum = 0;
for(int i = 1;i <= 10;i++) sum += i;
System.out.println("sum : "+sum);
System.out.println("avg : "+(double)sum/10);
System.out.println("프로그램 종료");
당연히 2번처럼 코드를 짜야한다. 그 이유는 물론 가독성 때문이다.
이제 모든 부분에서 좋은 형식에 대해 알아보자.
적절한 행 길이를 유지하자.
아무리 커다란 프로젝트라도 행 길이를 크지 않게 짤 수 있고, 행 길이가 짧을 수록 읽기 편하다.
하나의 파일에서 행 길이는 200줄 미만으로 짜자. 500줄을 넘기지 않는게 좋다.
물론, 짧을수록 좋다.
만약 코드 길이가 200라인을 넘어간다면, 하나의 클래스가 여러개의 일을 하고있을 수 있다.
-> SRP 위배!
개념은 빈 행으로 분리해라
아래 코드는 코딩테스트 문제 풀이 코드중 하나를 가져왔다.
이 코드는 개념을 빈 행으로 분리한 옳은 예시이다.
1) 좋은 예시
- (1) br과 st는 입력을 받기 위한 객체라서 한칸 띄었다.
- (2) int N, M은 입력받은 중요한 값들이라 한칸 띄었다.
- (3) for문이 시작되니 한칸 띄었다.
- (4) 새로운 for문이 시작되니 한칸 띄었다. st를 새로 생성하고 아래의 for문에서 사용할것이기 때문에 바로 위에 붙여줬다.
public class No1021 {
public static void main(String[] args) throws IOException {
List<Integer> list = new LinkedList<>();
//(1)
BufferedReader br = new BufferedReader(new InputStreamReader((System.in)));
StringTokenizer st = new StringTokenizer(br.readLine());
//(2)
int N = Integer.parseInt(st.nextToken()); //큐의 크기
int M = Integer.parseInt(st.nextToken()); //뽑아내려고하는 수의 개수
//(3)
for(int i=1;i<=N;i++){
list.add(i);
}
//(4)
st = new StringTokenizer(br.readLine());
for (int i = 0; i < M; i++) {
// ...
}
//생략
}
}
2) 위의 코드의 안좋은 예시
public class No1021 {
public static void main(String[] args) throws IOException {
List<Integer> list = new LinkedList<>();
BufferedReader br = new BufferedReader(new InputStreamReader((System.in)));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
for(int i=1;i<=N;i++){list.add(i);}
st = new StringTokenizer(br.readLine());
for (int i = 0; i < M; i++) {
//생략
}
//...
}
}
2)보다 1)의 가독성이 훨씬 좋은것을 알 수 있다.
이 코드는 단순해서 그 차이가 덜할 수 있지만, 코드가 복잡해질수록 이런 형식을 잘 지키는 것이 큰 도움이 될것이다.
세로 밀집도
줄바꿈이 개념을 분리한다면 세로 밀집도는 연관성을 의미한다.
서로 밀접한 관계가 있는 코드 행은 세로로 가까이 놓여야 한다
지역 변수
변수는 사용하는 위치에 최대한 가깝게 선언한다.
- 예를 들어 for문을 돌며 어떤 조건에 따라 count++를 해줘야한다면, 해당 for문이랑 최대한 가깝게 선언한다.
인스턴스 변수
인스턴스 변수는 클래스 맨 처음에 선언한다.
- 인스턴스 변수 간에 세로로 거리를 두지 않는다.
종속 함수
종속 함수끼리는 세로로 가까이에 배치한다.
- 한 함수가 다른 함수를 호출한다면 두 함수는 세로로 가까이 배치한다.
- 또한, 호출하는 함수를 호출되는 함수보다 먼저 배치해라.
개념적 유사성
명명법이 비슷하거나, 기본 기능이 유사하거나, 위처럼 종속성이 있거나 여러가지 방면에서 개념적 유사성이 있을 수 있다.
개념적 유사성(친화도)가 높은 코드끼리는 가까이에 배치한다.
가로 공백과 밀집도
가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한다.
int a = 10;
int b = 20;
int c = a + 2*b;
int d = Calc.sum(a, b);
할당 연산자('=')를 강조하기 위해 앞뒤로 공백을 준다.
할당문은 왼쪽요소와 오른쪽 요소가 분명히 나뉜다. 이때 공백을 주면 더 확실해진다.
우선순위에 따른 공백
곱셈 연산자( * )는 다른 연산자보다 우선순위에 앞서있다.
따라서 ' + '는 앞뒤로 공백을 주고, ' * '는 공백을 주지 않았다.
메서드 매개변수간의 공백
메서드내의 매개변수는 공백으로 분리했다. 쉼표를 강조해 인수가 별개라는 사실을 명백히 하기 위해서다.
들여쓰기
들여쓰기는 기본적으로 모두가 알거라고 생각된다.
그래서 항상 어떻게하는것이 좋을지 헷갈렸던 것중 하나를 소개하려고 한다.
(ex1)
if(isPrime(n) == true){
answer = 1;
}else answer = -1;
(ex2)
if(isPrime(n) == true){
answer = 1;
}else{
answer = -1;
}
(ex1)보다 (ex2)로 쓰는것이 낫다고 한다.
때때로 간단한 if문, 짧은 함수에서 (ex1)과 같이 들여쓰기를 무시하고픈 유혹이 생긴다.
이럴때 항상 원점으로 돌아가서 (ex2)처럼 들여쓰기를 하는것을 추천한다.
Java Class Declaration : Class 내부 코드 순서
1. static 변수
public -> protected -> package -> private 순서
2. instance 변수
public -> protected -> package -> private 순서
3. 생성자
4. 메서드
위에서 말했듯이, public 메서드에서 호출되는 private 메서드는 그 아래에 둔다.
Team Coding Convention
팀 단위로 개발을 할때는 미리 규칙을 정하고 시작하는것이 좋다.
기본은 개발 언어(Java)의 컨벤션이 우선이다.
그러나 다른 부분은 팀 컨벤션을 정하고, 따라야한다.
ex) DB 컬럼 명은 snake_case로, Java에서는 camelCase로 작성한다.
Google Java Style Guide
https://google.github.io/styleguide/javaguide.html
Naver Hackday Java Convention
'기타 > Book Review' 카테고리의 다른 글
[CleanCode] 클린코드 리뷰_7장 : 오류처리 (0) | 2023.06.24 |
---|---|
[CleanCode] 클린코드 리뷰_6장 : 객체와 자료구조 (0) | 2023.06.21 |
[CleanCode] 클린코드 리뷰_ 4장 : 주석 (0) | 2023.06.16 |
[Clean Code] 클린코드 리뷰_ 3장 : 함수 (0) | 2023.06.15 |
[Clean Code] 클린코드 리뷰_ 2장 : 의미있는 이름 (1) | 2023.06.13 |