일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- react
- 자료구조
- 서버구축
- url parsing
- 백준알고리즘
- 라우터
- 토이프로젝트
- 다익스트라 알고리즘
- 탐욕법
- sort
- 알고리즘
- 완전탐색
- mysql
- nodejs
- 백준
- Router
- ELB
- 리액트
- EC2
- 스터디
- 동적프로그래밍
- EventListener
- AWS
- java
- Spring Boot
- 브루트포스
- Algorithm
- 정렬
- BFS
- spring
- Today
- Total
공부하는 블로그
Others | Book Review : 읽기 좋은 코드가 좋은 코드다 본문
# INTRO
분량이 적다고 항상 좋은 코드는 아니다. 적은 분량도 중요하지만 이해를 위한 시간을 최소화 하는 것이 더 좋은 목표다.
# Part 01. 표면적 수준에서의 개선
표면적 수준 ? 좋은 이름, 좋은 설명, 코드 정렬
1. 이름에 정보 담기
> 보편적(tmp, retval, ...)이지 않고 구체적으로, 접두사나 접미어 사용
> 루프 인덱스(i, j, k, ...) : 어떤 인덱스인지 이름 붙이는게 좋다. ex)user_i(ui), club_i(ci), ...
> 단위 정보를 변수에 담는 것도 좋다.
> 헝가리언 표기법? 마이크로소프트에서 사용하는 표기법으로 변수의 타입을 이름 앞에 붙여서 사용한다. (inumber, dnumber, ...)
> 사용 범위가 넓으면 긴 이름의 변수를 사용하는 것이 좋다.
> 클래스, 멤버변수, 로컬변수 등 각각의 변수명의 Formatting Convention을 다르게 하여 구분하면 좋다.
2. 오해할 수 없는 이름들
> 경계를 포함하는 한계값 : min, max / 경계를 포함하는 범위 : first, last / 경계의 마지막을 포함하지 않는 범위 : begin, end
> boolean 변수 prefix : is, has, can, should / 의미를 부정하는 용어를 피하자
> get*() : 가벼운 접근자. 계산시간이 오래걸리지 않음. 전체를 조회하는 경우는 다른 prefix를 사용하도록 하자.
cf. 과거의 C++ 표준 라이브러리의 list.size()는 O(n)의 시간복잡도를 가지고 있었다. 따라서 엄청난 시간이 소요되었음. 최근에는 O(1)로 변경됨
3. 미학
> 좋은 소스코드는 눈을 편하게 해야한다. : 빈칸, 정렬, 코드순서 등등 고려해보자!
> 일정한 줄바꿈 등등 일관성 있는 패턴을 가지도록 하자.
> 코드를 예쁘게 개선시키는 과정은 표면적인 가독성 이상의 결과를 가져올 수도 있다. (중복코드를 메서드화, 모듈화와 같은 결과)
> 코드의 열(들여쓰기) 맞추기
> 변수의 순서 또한 규칙을 정하여 일관성 있게 선언하도록 하자. (ex. HTML 폼의 input 순서 or 중요도 순서)
> 선언문을 블록으로 구성 --> 논리적 영역에 따라 그룹화
> 코드를 문단화 하자. 문단의 시작에는 간단한 설명 주석문
4. 주석에 담아야 하는 대상
> 코드에서 빠르게 유추할 수 있는 내용은 주석으로 달지 말기
> 나쁜 이름에는 주석을 달지 말고 이름을 고쳐라. : 좋은 코드 > 나쁜 코드 + 좋은 주석
> 코드를 짜며 들었던 나의 생각들을 기록하는 것도 좋다. (ex. 수정방향 제시, 최적화 내용, 버그내용)
> 코드의 결함은 // TO DO : 로 설명하도록 하자
> 설정한 상수에 대한 설명을 적어두도록 하자.
> 항상 내가 아닌 내 코드를 처음보는 사람들을 기준으로 생각해보자..
> File 수준의 주석도 달도록 하자 : 큰그림 주석
> 요약주석 : 몇몇의 덩어리로 이루어진 긴 코드에서 좋다.
> 주석을 쓰기 어려워하지 말고 일단 써라.. 그냥 써라..
1. 그냥 무조건 쓴다 2. 주석의 개선사항을 확인 3. 개선
> 입출력 예를 보여주는 것도 좋다.
# Part 02. 루프와 논리를 단순화하기
1. 읽기 쉽게 흐름제어 만들기
> 비교(==, >=, <= ...) : 왼쪽 값은 유동적인 값, 오른쪽 값은 더 고정적인 값으로 비교의 대상이 되는 값이 들어간다.
> if/else문
-- 부정이 아닌 긍정 조건을 다루자. if(a!=b) {} else {} 보다는 if(a==b) {} else {}
-- 간단한 것 먼저 처리
-- 더 흥미롭고 확실한 것 먼저 처리
-- 삼항연산자는 정말 간단한 경우에만 사용하도록 하자. 코드는 짧아질지 몰라도 읽기 어려워질 수 있음
> do/while문
-- 코드를 역순으로 읽어야해서 불편하다. 피하도록 하자
> 반복문이나 조건문을 중첩해서 사용하는 것은 최소화하자. 그렇지 않으면 코드를 읽을 때 어느 수준의 블록에 있는지 머리속으로 계속해서 체크해주어야 한다.
2. 거대한 표현을 잘게 쪼개기
> 설명변수를 사용하도록 하자.
-- if(data.split(":").trim() == "root") {} --> String username = data.split(":").trim(); if(username == "root") {}
> boolean형 요약변수를 사용하는 것도 좋다.
> 드모르간의 법칙을 사용하자
3. 변수와 가독성
> 불필요한 임시 변수, 흐름 제어 변수는 제거하도록 하자
> 변수의 범위를 좁히도록 하자
-- 전역변수는 정말 필요할 때만 선언
-- 코드를 읽는 사람이 한꺼번에 생각해야 하는 변수의 수를 줄인다.
> 메서드를 static으로 만들면 클래스 멤버 접근을 제한할 수 있다. 해당 메서드가 독립적이라는 사실을 알려줄 수 있음.
> 변수의 선언은 해당 변수를 사용하는 로직을 수행하기 바로 직전에 선언해주자.
> 값을 한번만 할당하는 변수를 선호하자. 변수값이 달라지는 곳이 많을수록 현재의 값을 추측하기 어려워진다.
# Part 03. 코드 재작성하기
1. 상관없는 하위문제 추출하기
> 작성된 함수의 상위수준의 목적을 잘 생각해보고 해당 함수 내에서 상위 수준의 목적과는 상관 없는 로직은 따로 하위 메서드를 작성하여 목적에 맞는 로직에만 집중할 수 있도록 한다.
> 이렇게 쪼개진 하위 메서드들은 다른 곳에서도 재사용이 가능하다.
> 유틸리티 로직나 일반적인 목적의 로직을 하위 메서드로 분리하여 다른 곳에서도 재사용하도록 하자!
2. 한번에 하나씩
> 복잡한 코드는 수행하는 작업을 쭉 나열해보고 한번에 하나의 작업을 수행하는 메서드나 클래스로 분리하도록 하자.
3. 코드 분량 줄이기
> 표준 라이브러리를 잘 활용하여 코드 분량을 줄여보자.
Reference
'Others' 카테고리의 다른 글
Design Pattern | Factory Method (0) | 2020.09.14 |
---|---|
Design Pattern | Singleton (0) | 2020.09.14 |
Flowchart 작성법 (0) | 2020.09.10 |