형식 맞추기
뚜껑을 열었을 때 독자들이 코드가 깔끔하고, 일관적이며, 꼼꼼하다고 감탄하면 좋겠다. 질서 정연하다고 탄복
하면 좋겠다 모률을 읽으며 두 눈이 휘둥그래 놀라면 좋겠다. 전문가가 짰다는 인상을 심어주면 좋겠다. 그 대신에
술 취한 뱃사람 한 무리가 짜놓은 듯 어수선해 보인다면 독자들은 프로젝트의 다른 측면도 똑같이 무성의한 태도로
처리했으리라 생각할 것이다.
-요약-
읽히기 편한 코드 형식을 추구해라.
팀이 정한 규칙을 준수하고 일관성을 유지하라.
1. 읽히기 편한 코드 형식
1.1 신문 기사처럼 코드를 작성하라
신문은 가장 중요한 기사가 상단에 있고 아래로 내려가면서 그에 대한 세부적인 기사들이 나열된다.
코드 또한 추상화단계가 높은 코드가 상단에 위치하고 그에 종속되는 코드가 바로 아래에 오는 형식이 읽히기 좋다.
[종속 코드가 바로 아래에 오는 메서드 배치]
@Transactional
public IdDto addAccount(AccountAddReq accountAddReq) {
verifyDuplicateEmail(accountAddReq.getEmail());
verifyDuplicateNickname(accountAddReq.getNickname());
String encodePassword = bCryptPasswordEncoder.encode(accountAddReq.getPassword());
String profile = imageService.uploadImage(accountAddReq.getProfile(), path);
Account account = accountAddReq.toAccount(encodePassword, profile);
Account savedAccount = accountRepository.save(account);
return new IdDto(savedAccount.getId());
}
private void verifyDuplicateEmail(String email) {
if (email != null) {
if (accountRepository.existsByEmail(email)) {
throw new BusinessLogicException(ExceptionCode.DUPLICATION_EMAIL);
}
}
}
private void verifyDuplicateNickname(String nickname) {
if (nickname != null) {
if (accountRepository.existsByNickname(nickname)) {
throw new BusinessLogicException(ExceptionCode.DUPLICATION_NICKNAME);
}
}
}
addAccount()에 사용된 verifyDuplicateEmail()과 verifyDuplicateNickname()을 바로 이어지게 메서드를 배치하였다.
코드를 읽는 사람은 종속된 코드를 바로 확인할 수 있어서 보기 편하다.
1.2 수직거리
1.2.1 연관되거나 유사한 개념의 메서드들은 가깝게 배치되면 좋다
유사한 개념의 메서드를 가까이 배치하면 메서드의 역할을 쉽게 예측할 수 있기 때문에 코드를 읽기 편해진다.
[개념 유사성에 따른 메서드 배치]
@Transactional
public IdDto addAccount(AccountAddReq accountAddReq) {
.
.
.
}
@Transactional
@CacheEvict(key = "#loginAccountId", value = {"findAccount", "findLoginAccount"})
public IdDto modifyAccount(Long loginAccountId, AccountModifyReq accountModifyReq) {
.
.
.
}
@Transactional
@CacheEvict(key = "#loginAccountId", value = {"findAccount", "findLoginAccount"})
public void removeAccount(Long loginAccountId) {
.
.
.
}
@Cacheable(key = "#accountId", value = "findAccount")
public AccountDetailsRes findAccount(Long accountId) {
.
.
.
}
Account에 대한 CRUD 작업을 서로 가깝게 배치하였다.
코드를 읽는 사람은 해당부분이 CRUD에 관한 것을 파악하고 메서드의 역할을 쉽게 예측할 수 있다.
1.2.2 변수는 사용되는 위치와 최대한 가깝게 구성하는 것이 코드를 이해하기 좋다
지역 변수같은 경우 사용될 위치와 최대한 가깝게 구성하는 것이 좋다.
해당 변수가 어느 부분에 사용되고 있는지를 쉽게 파악할 수 있기 때문이다.
단, 인스턴스 변수같은 경우 관념상 클래스 맨 첫 부분에 선언하는 것이 좋다.
1.2.3 상수는 사용되는 곳의 함수에 인자로 넘겨주는 것이 좋다
상수가 어디에 사용되는지 확인 할 수 있기 때문에 상수는 사용되는 곳의 함수에 인자로 넘겨지는 것이 좋다
[상수를 인자로 받는 메서드]
@PostMapping
public ResponseEntity<ImageUploadRes> imageUpload(@Valid @ModelAttribute ImageUploadReq imageUploadReq) {
List<String> imagePaths = imageService.uploadImage(imageUploadReq.getImages(), path);
return new ResponseEntity<>(ImageUploadRes.of(imagePaths), HttpStatus.OK);
}
path는 특정 경로를 나타내는 상수이다.
path를 인자로 받지 않고 uploadImage() 내부에서 바로 사용할 수 있지만, 그러면 path라는 특별한 상수가 어디에 사용되는지 파악하기 어려울 수 있다.
uploadImage()에 인자로 path를 받음으로써 image를 업로드할 때 특정 path에 저장되는 것을 쉽게 파악할 수 있다.
1.3 들여쓰기
코드에 들여 쓰기를 준수해서 각 계층을 구분하고 읽기 편한 형식으로 만드는 것이 좋다
가독성에 좋지 않기 때문에 짧은 조건문에 들여 쓰기를 빼는 것은 지양해한다.
2. 팀이 정한 규칙을 따라라
팀 내에 정해진 규칙이 있다면 해당 규칙을 따르는 것으로 코드의 일관성을 지켜야 한다.
일관성이 있는 코드는 쉽게 예상 가능하고 이해하기 좋다
또한 일관된 형식은 유지보수에도 좋다.
'책 > 클린코드' 카테고리의 다른 글
9. 단위 테스트 (0) | 2023.06.23 |
---|---|
6. 객체와 자료 구조 (0) | 2023.06.18 |
4. 주석 (0) | 2023.06.18 |
댓글