Books/클린코드

[클린코드] 1장 깨끗한 코드

유로띠 2021. 12. 17. 00:53
반응형

클린 코드 독서 1일차

 

 

 

🧹 깨끗한 코드


나쁜 코드는 무엇일까?

👎 성능이 나쁜 코드
불필요한 연산이 있어서 개선이 필요한 코드

 

👎 의미가 모호한 코드
이해하기 어려운 코드
네이밍과 그 내용이 다른 코드

const c = await this.validateCourse();

함수를 보면 강의에 대해 유효성을 검사하는 것 같다.


어떤 유효성을 검사한 것일까? 🧐

정상적인 강의인지? 수강생이 해당 강의를 봐도 되는지?

수강이 가능한 강의인지? 필수로 봐야 하는 강의 인지?
함수를 봐서는 알 수가 없다.

(함수 리팩토링은 다음 장에..)


또한, 이름 c는 아무런 의미도 드러나지 않는다.

 

의도가 드러나는 이름을 사용하면 코드의 이해와 변경이 쉬워진다.

const requiredCourse; //필수강의구나!
const courses; // 강의목록이구나!

 

👎 중복된 코드

비슷한 내용인데 중복되는 코드

 

 

매월 20개씩 사용할 수있는 티켓이 있고

티켓을 이용하여 물건을 구매하거나 양도할 수 있다고 생각해보자.

구매() {
  사용자 티켓 확인
  사용자의 티켓 감소
  구매한 제품 수량 감소
  구매 완료
}

양도() {
  사용자의 티켓 확인
  양도할 사용자 확인
  사용자의 티켓 감소
  구매한 제품 수량 감소
  양도할 사용자에게 제품 양도
  구매 완료
}

구매와 양도의 기능에서

사용자의 티켓 감소, 구매한 제품 수량 감소

기능이 중복되어 보여 개선이 필요해 보인다. 😏

 

 

깨끗한 코드

 

 

비야네 스트롭스트룹

우아하고 효율적인 코드를 좋아한다.
논리가 간단해야 버그가 숨어들지 못한다.
의존성을 최대한 줄여야 유지보수가 쉬워진다.
오류는 명백한 전략에 의거해 철저히 처리한다.
성능을 최적으로 유지해야 사람들이 원칙 없는 최적화로 코드를 망치려는 유혹에 빠지지 않는다.
깨끗한 코드는 한 가지를 제대로 해야 한다.

 

그래디 부치

깨끗한 코드는 단순하고 직접적이다.
깨끗한 코드는 잘 쓴 문장처럼 읽힌다.
깨끗한 코드는 결코 설계자의 의도를 숨기지 않는다.
오히려 명쾌한 추상화와 단순한 제어문으로 가득하다.

 

론 제프리스

모든 테스트를 통과한다.
중복이 없다.
시스템 내 모든 설계 아이디어를 표현한다.

 

 

 

워드 커닝햄

코드를 읽으면서 짐작했던 기능을 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 되겠다.
코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드라 불러도 되겠다.

 

 

 

즉,

클린 코드는 다음과 같다
✅ 성능이 좋은 코드
✅ 의미가 명확한 코드
✅ 중복이 제거된 코드

 

 

 

보이스카우트 법칙

Always leave the campground cleaner than you found it.
캠프장은 처음 왔을 때 보다 더 깨끗하게 해 놓고 떠나라.

 

 

한꺼번에 많은 시간과 노력을 투자해서 정리하지 말고
변수 이름 하나를 개선하고
조금 긴 함수 하나를 분할하고
약간의 중복을 제거하고
복잡한 if문 하나를 정리 하면 된다.

 

 

 

 

👀 의미 있는 이름


통일성 있는 단어를 사용하기

controller / manager / driver는 비슷한 단어이기에 섞어 쓰면 혼란만 야기한다.

일관성 있는 어휘 코드를 사용하자.

 

그럼 이것은 어떤가?
add / insert / append
비슷한 단어니까 통일성 있게 add 만 사용해야 할까?
그렇지 않다. 주어진 상황과 맥락이 다르다면 그것에 맞게 사용해야 한다.

 

변수명에 타입 넣지 않기

타입이 바뀌어도 변수 이름은 바뀌지 않기 때문에 변수명에 타입을 넣지 말자.

String phoneString ( 🙅‍♂️ ) -> phone

Int salePriceAmount ( 🙅‍♂️ ) -> salePrice

List<Course> courseList, courses

 

🟢 인터페이스 클래스와 구현 클래스

인터페이스 클래스에 접두어 I는 주의를 흩트리고 과도한 정보를 제공한다.
책에서는 차라리 구현 클래스에 Impl(Implement)를 인코딩한다.

public interface IPublishFactory ( 🙅‍♂️ ) -> publishFactory
public class publishFactoryImpl

찾아보니 다양한 곳에서 접두어 I 를 사용하는 것을 지양하는 것 같다.

 

📌 참고
typeScript-book
google styleguide
github issue

 

검색하기 쉬운 이름을 사용하라

문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다.

 

다음과 같은 금액을 계산하는 코드가 있다.

const amount = (price * (100 - 22)) / 100;

22가 무엇을 의미하는지 알 수 있을까? 🧐
위 코드는 제세공과금을 제외한 금액을 구하는 코드이다.

 

5만원을 초과하는 경품에 당첨되었을 때 내야 하는 기타 소득세이며 물품 가격에 22%를 내야 한다.


만약 제세공과금이 변경되었다면 22를 검색할 때 쉽게 찾지 못할 것이다.

 

다음과 같이 검색하기 쉬운 이름을 사용해야 검색이 쉬워진다.

const CUSTOMER_TAX_PERCENT = 22;
const amount = (price * (100 - CUSTOMER_TAX_PERCENT)) / 100;

 

 

 

Google Java Naming Guide


 

구글의 Java Naming Guide 입니다.

 

🟢 Package Naming Guide

All lower case, no underscores

io.example.deepspace ( 🙆‍♂️ )

io.example.deepSpace ( 🙅‍♂️ )
io.example.deep_space ( 🙅‍♂️ )

 

🟢 Class Naming Guide

Upper Camel Case

//클래스는 명사, 명사구를 사용한다. 동사는 사용하지 않는다.
Character
ErrorCode

//인터페이스는 명사, 명사구 또는 형용사를 사용한다.
List
Readable

//테스트 클래스는 Test로 끝낸다.
PingControllerTest

 

🟢 Method Naming Guide

Lower Camel Case

//메서드는 동사,동사구를 사용한다.
sendMessage
deletePage

 

🟢 Constant Names

All Upper case letters

static final Joiner COMMA_JOINER = Joiner.on(',');

 

 

 

코드를 개선하려는 노력을 중단해서는 안된다

 

 

반응형