클린코드 3장 함수

 

작게 만들어라

첫째 규칙은 ‘작게’ 다. 둘째 규칙은 ‘더 작게’ 다.

규칙의 근거를 대기는 곤란하지만, 함수가 작을 수록 더 좋다.

if/else, while 등에 들어가는 블록은 한 줄이어야 한다. → 바깥 함수는 작아지고, 블록 안에서 호출하는 함수 이름만 적절히 짓는다면 코드를 이해하기 쉬워진다.

즉, 중첩 구조가 생길만큼 함수가 커져서는 안된다.

들여쓰기가 1단이나 2단을 넘어서면 안된다.

한가지만 해라!

함수는 한 가지를 해야한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다.

지정된 함수 이름 아래에서 추상화 수준이 하나인 단계만 수행한다면 그 함수는 한 가지 작업만 하는 것이다.

단순히 다른 표현이 아니라 의미 있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈이다,

함수 당 추상화 수준은 하나로!

함수가 확실히 ‘한 가지’ 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 한다.

위에서 아래로 코드 읽기 (내려가기) - 코드는 위에서 아래로 이야기 처럼 읽혀야 좋다. 위에서 아래로 프로그램을 읽으면 함수 추상화 수준이 한 번에 한 단계씩 낮아진다.

TO 설정 페이지와 해제 페이지를 포함하려면, 
설정 페이지를 포함하고, 테스트 페이지 내용을 포함하고, 헤제 페이지를 포함한다.
	TO 설정 페이지를 포함하면,
	슈트이면 슈트 설정 페이지를 포함한 후 일반 설정 페이지를 포함한다.

	TO 슈트 설정 페이지를 포함하려면, 
	부모 계층에서 "SuiteSetUp" 페이지를 찾아 include 문과 페이지 경로를 추가한다.
	
	TO 부모 계층을 검색하려면, ....

Switch 문

switch 문을 작게 만들기는 어렵다.

또, 한가지만 하는 switch 문을 만들기 어렵다 → 본질적으로 N가지를 처리하기 때문

불행하게도 switch 문을 완전히 피할 방법은 없다, 하지만 각 switch 문을 저차원 클래스에 숨기고 절대로 반복하지 않는 방법이 있다. 물론 다형성(polymorphism)을 이용한다.

서술적인 이름을 사용하라!

함수가 하는 일을 조금 더 잘 표현하면 훨씬 좋은 이름이다. (testableHtml → SetupTeardownIncluder.render)

“코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 된다.”

이름이 길어도 괜찮다. 겁머긍ㄹ 필요 없다,. 길고 서술적인 이름이 짧고 어려운 이름보다 좋다.

함수 이름을 정할 때 여러 단어가 쉽게 익히는 명명법을 사용한다.

서술적인 이름을 사용하면 개발자 머릿속에서도 설계가 뚜렷해지므로 코드를 개선하기 쉬워진다.

이름을 붙일 때는 일관성이 있어야 한다. 모듈 내에서 함수 이름은 같은 문구, 명사, 동사를 사용한다.

함수 인수

가장 이상적인 인수개수는 0개.

다음은 1개, 다음은 2개, 3개는 가능한 피하는 편이 좋다.

4개 이상은 특별한 이유가 필요하다. (특별한 이유가 있어도 사용하면 안 된다..)

인수는 어렵고, 인수는 개념을 이해하기 어렵게 만든다.

코드를 읽는 사람이 현 시점에서 중요하지 않은 세부사항을 알아야 한다.

테스트 관점에서 보면 인수는 더 여럽다. 갖가지 인수 조합으로 함수를 검증하는 테스트 케이스를 작성한다고 상상해보면 더 어렵다.

출력 인수는 입력 인수 보다 더 이해하기 더 어렵다.

SetupTeardownIncluder.render(pageData) → pageData 객체 내용을 렌더링 하겠다고 읽힌다.

많이 쓰이는 단항 형식

함수에 인수 1개를 넘기는 이유로 가장 흔한 경우는 두 가지이다.

  • 인수에 질문을 던지는 경우 → booelan fileExists(”MyFile”)
  • 인수를 뭔가로 변환해 결과를 반환하는 경우 -< InputStream fileOpen(”MyFile”)

다소 드물게 사용하지만 그래도 아주 유용한 단항 함수 형식이 이벤트다. 이벤트 함수는 입력 인수만 있다. 출력 인수는 없다. → passwordAttemptFailedNtimes(int attemptes)

이런 경우가 아니면 단항 함수는 가급적 피한다. → void includeSetupPageInto(StringBuffer pageText)

void transform(StringBuffoer out) 보다는 StringBuffer transform(StringBuffer in)

플래그 인수

함수에 bool 값을 전달하는 것은 함수가 여러 역할을 한다고 말하는 것이라 추하다!

이항 함수

인수가 2개인 함수는 인수가 1개인 함수보다 이해가 어려움.

writeField(name) 보다 writeField(outputStream, name) 이 이해하기 어려움.

이항 함수가 무조건 나쁜 것은 아님.

writerFiled(outputStream, name) 에서 outputStream 을 클래스 구성원으로 만들어서 outputStream.writeField(name) 으로 호출을 하거나, outputStream 을 클래스 구성 변수로 만들어서 인수를 넘기지 않거나.. 등등 의 방법으로 줄이는 것이 좋다.

삼항 함수

인수가 3개인 함수는 인수가 2개인 함수보다 이해가 어려움. 그래서 신중해야 함.

Circle makeCircle(double x, double y, double radius) 가 있을 때 Circle makeCircle(Point center, double radius) 로 바꾸면 보기 좋다. 단순히 x, y 를 묶은 것 외에도 묶으면서 이름을 남기기 때문에 개념을 표현하게 되기 때문.

인수 목록

String.format 처럼 인수 개수가 가변적인 함수도 필요.

public String format(String format, Object… args) 형태로 로 구현이 되기 때문에 이항 함수 이다.

동사와 키워드

함수의 의도나 인수의 순서와 의도를 제대로 표현하려면 좋은 함수 이름은 필수.

단항 함수는 함수와 인수가 동사/명사 쌍을 이뤄야 한다.

write(name) 은 누구나 바로 이해 한다.그러다 조금 더 나은 이름은 writeField(name)

함수 이름에 인수 이름을 넣는 것도 좋다 assertEqual 보다 assertExpectEqualsActural(expected, actual) 이 좋다. 이러면 인수의 순서를 기억할 필요는 없다.

부수 효과를 일으키지 마라!

부수 효과는 거짓말이다.

함수에 한가지만 하겠다고 약속하고 남몰래 다른짓을 하는 것이다.

때로는 함수로 넘어온 인수나 시스템 전역 변수를 수정한다.

출력 인수

일반적으로 인수는 함수 입력으로 해석한다.

public void appendFooter(StringBuffer report) 라는 함수가 있을 때 인수를 빼고 StringBuffer 는 클래스 인스턴스 변수로 만들어서 report.appendFooter() 같은 형태로 개선이 필요함.

명령과 조회를 분리하라!

함수는 뭔가를 수행하거나 뭔가에 답허가나 둘 중 하남나 해야 한다. 둘다 하면 안된다.

객체 상태를 변경하거나 아니면 객체 정보를 반환하거나 둘 중 하나만.. 둘다 하면 혼란을 초래한다.

오류 코드보다 예외를 사용하라!

오류 코드를 사용하기보다는 exception 을 raise 시켜라.

Try/Catch 블록을 뽑아내기

try/catch 는 추하다. 정상 동작과 오류 처리 동작을 뒤 섞는다.

try/catch 블록을 별도 함수로 뽑아내는 것이 좋다.

try {
	deletePage(page);
	registry.deleteReference(page.name);
	configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
	logger.log(e.getMessage());
}

보다는...

publiv void delete(Page page) {
	try {
		deletePageAndAllReferences(page);
	}
	catch (Exception e) {
		logError(e);
	}
}

private void deletePageAndAllReferences(Page page) {
	deletePage(page);
	registry.deleteReference(page.name);
	configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) { 
	logger.log(e.getMessage());
}

오류 처리도 한 가지 작업이다

함수는 한 가지 작업만 해야한다.

반복하지 마라!

그냥 반복하지 마라. 중복을 없애라..

구조적 프로그래밍

데이크르스트라는 모든 함수와 함수 내 모든 블록에 입구와 출구가 하나만 존재해야 함.

즉, 함수는 return 문이 하나여야 한다.

루프 안에서 break, contiune 를 사용하면 안되고 goto는 당연히 절대 안된다.

함수를 어떻게 짜죠?

소프트웨어를 짜는 행위는 여느 글짓기와 비슷하다.

논문이나 기사를 작성할 때는 먼저 생각을 기록한 후 읽기 좋게 다듬는다. 초안은 서투르고 어수선하고, 원하는 대로 읽힐 때까지 말을 다듬고 문장을 고치고 문단을 정리한다.

함수를 짤때도 마찬가지다. 처음에는 길고 복잡하고 들여쓰기 단계도 많고 중복된 루프도 많다.

인수 목록도 아주 길다. 이름은 즉흥적이고 코드는 중복된다. 하지만 그 서투른 코드를 빠짐없이 테스트하는 단위 테스트 케이스를 만들고 코드를 다듬고, 함수를 만들고 이름을 바꾸고 중복을 제거한다. 때로는 이름을 바꾸기도 하고 전체 클래스를 쪼개기도 하고 메소드를 바꾸기도 한다.

이 와중에도 코드는 항상 단위 테스트를 통과한다.

결론

모든 시스템은 특정 응용 분야 시스템을 기술할 목적으로 프로그래머가 설계한 도메인 특화 언어로 만들어진다.

함수는 그 언어에서 동사며, 클래스는 명사다.

높은 레벨의 프로그래머는 시스템을 구현할 프로그램이 아니라 풀어갈 이야기로 여긴다. 프로그래밍 언어라는 수단을 사용해 좀 더 풍부하고 좀 더 표현력이 강한 언어를 만들어 이야기를 풀어간다.

클린코드 2장 의미 있는 이름

 

의도를 분명히 밝혀라

좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.

좋은 이름을 지으면 자신을 포함해 코드를 읽는 사람이 조금 더 행복해질 수 있다.

변수나 함수 그리고 클래스 이름은 다음과 같은 굵직한 질문에 모두 답해야한다. (따로 주석이 필요하면 의도를 들어내지 못했다는 것)

  • 변수/함수/클래스의 존재의 이유는?
  • 수행 기능은?
  • 사용 방법은?

그릇된 정보를 피하라

코드에 그릇된 단서를 남겨서는 안 된다.

나름대로 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용해서 안된다.

서로 흡사한 이름을 사용하지 않도록 주의한다.

유사한 개념은 유사한 표기법을 사용한다.

이름으로 그릇된 정보를 제공하는 끔찍한 예가 소문자 L이나 대문자 O 변수다. (아래 코드)

int a = l;
if ( O == 1 ) {
	a = O1;
} else {
	l = 01;
}

의미 있게 구분하라

copyChars 메소드의 파라미터 변수명으로 a1, a2 같이 하지 말고.. source, destination 같은 것을 사용하면 더 알기 쉽다.

Product 라는 클래스가 있을 때 다른 클래스를 ProductInfo /. ProductData 로 하지 말자. 어떤것인지 알기 어렵다.

또 a 나 the 등의 무의미한 접두사를 붙이지 말자 (zork 라는 변수가 있다는 이유로 theZork 라는 새로운 변수를 쓰지 말자)

변수명에 variable 이라는 단어는 결단코 금물이다. 표 이름에 table 이라는 단어도 마찬가지다. (NameString 과 Name보다 뭐가 더 나은가?)

발음하기 쉬운 이름을 사용하라

발음 하기 어려운 이름은 토론하기도 어렵다.

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

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

MAX_CLASSES_PER_STUDENT 는 grep 으로 찾기 쉽지만, 숫자 7은 은근히 까다롭다.

인코딩을 피하라

인코딩한 이름은 거의가 발음하기 어려우며 오타가 생기기도 쉽다.

헝가리식 표기법

이름길이가 제한된 언어를 사용하던 옛날에 어쩔 수 없이 썼다. 첫 글자에 유형을 표기해줬는데 요즘 언어에서는 큰 의미가 없다. (ex: String sName, String phoneString) → 이렇게 했을 때 type을 바꾸게 되어도 변수명은 그래도 있게 된다.

멤버 변수 접두어

IDE나 컴파일러가 알아서 잘 해주기 때문에.. 할필요가 없다.

인터페이스 클래스와 구현 클래스 - 인터페이스 클래스 이름과 구현 클래스 이름 중 하나를 인코딩해야 한다면 구현 클래스 이름을 택할 것. SharpeFactoryImp 나 CShapeFactory 가 IShapeFactory 보다 좋다

자기 기억력을 자랑하지 마라

문자 하나만 사용하는 변수 이름은 문제가 있음. (루프에서 반복 횟수를 세는 변수 i,j,k 는 괜찮다.. l은 절대 안된다.) 혹은 루프 범위가 아주 작고 다른 이름과 충돌하지 않을 때는 괜찮다. 그 외에는 적절하지 않다.

클래스 이름

클래스 이름과 객체 이름은 명사나 명사구가 적합하다.

Customer, WikiPage, Account, AddressParser 등등..

Manager, Processor, Data, Info 등과 같은단어는 피하고 동사는 사용하지 않는다.

메서드 이름

메서드 이름은 동사나 동사구가 적합하다.

postPayment, deletePage, save 등등..

자바의경우 접근자(accessor), 변경자(mutator), 조건자(predicate)는 get, set, is 를 앞에 붙인다. → 언어에 따라 다르다.

기발한 이름을 피하라

이름이 너무 기발하면 저자와 유머 감각이 비슷한 사람만, 그리고 농담을 기억하는 동안만 이름을 기억한다.

한 개념에 한 단어를 사용하라

추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다.

예를 들면 똑같은 메서드를 클래스마다 fetch, retrieve, get 으로 제각각 부르면 혼란스럽다.

일관성 있는 어휘는 코드를 사용할 프로그래머가 반갑게 여길 선물이다.

말장난을 하지 마라

한 단어를 두 가지 목적으로 사용하지 마라.

해법 영역에서 가져온 이름을 사용하라

코드를 읽은 사람도 프로그래머를 사실을 명심한다. 그러므로 전산 용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮다.

VISITOR 패턴에 친숙한 프로그래머는 AccountVisitor 라는 이름을 금방 이해하고 JobQueue 를 모르는 프로그래머는 없다.

기술 개념에는 기술 이름이 가장 적합한 선택이다.

문제 영역에서 가져온 이름 사용하라

적절한 프로그래머 용어가 없으면 문제 영역에서 이름을 가져온다.

의미 있는 맥락을 추가하라

스스로 의미가 분명한 이름이 없지는 않지만 대다수 이름은 그렇지 못하다.

그래서 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다. 모든 방법이 실패하면 마지막 수단으로 접두어를 붙인다

firstName, lastName, street, houseNumber, city, state, zipcode 라는 변수가 있을 때 훝어보면 주소라는 사실을 금방 알아 챈다. 하지만 state 라는 변수 하나만 사용한다면 state가 주소 일부라는 사실을 금방 알아챌 수 없다.

addr이란는 접두어를 붙이면 조금 더 명확해진다. (addrFirstName, addrLastName, addrStreet, addrHouseNumber, addrCity, addrState, addrZipcode) → 물론 Address라는 클래스를 만다는 것이 더 좋다.

불필요한 맥락을 없애라

고급 휘발유 충전소라는 애플리케이션을 짠다고 할 때, 모든 클래스 이름을 GSD로 시작하겠다는 것은 전혀 바람직하지 못한다.

일반적으로 짧은 이름이 긴 이름보다 좋다. (단, 의미가 분명한 경우에 한해서)

마치면서

좋은 이름을 선택하려면 설명 능력이 뛰어나야 하고 문화적인 배경이 같아야 한다.

좋은 이름을 선택하는 능력은 기술, 비즈니스, 관리 문제가 아니라 교육 문제다.

사람들이 이름을 바꾸지 않으려는 이유 하나는 다른 개발자가 반대할까 두려워서다. → 하지만 좋은 이름으로 바꾸면 오히려 반갑고 고맙다.

클린코드 1장 깨끗한 코드

코드가 존재하리라

코드가 사라질 가망은 전혀 없음 →코드는 요구사항을 상세히 표현하는 수단임.

요구사항을 모호하게 줘도 우리 의도를 정확히 꿰뚫어 프로그램을 완벽하게 실행하는 그런 기계가 나오길 기대하지만 절대 불가능하다. → 창의력과 직관을 보유한 인간도 고객의 막연한 감정만 갖고는 성공적인 시스템을 구현하지 못한다.

나쁜 코드

80년대 후반 킬러 앱 하나를 구현한 회사가 있었으나, 제품 출시 주기가 점점 늘어지기 시작했음 → 이전에 있던 버그가 수정되지 않고 남아지고 점점 느려짐 → 회사 망함

이유? 출시에 바빠 코드를 마구 짰다가 기능을 추가할 수록 코드가 엉망이 되어 감당 불가한 수준에 이르렀음. (즉, 나쁜 코드 탓)

나쁜 코드가 치르는 대가

  • 코드를 고칠 때 마다 엉뚱한 곳에서 문제가 생김
  • 간단한 변경이 없음.
  • 매번 얽히고 설킨 코드를 해독 해서 얽히고 설킨 코드를 추가 함.
  • 나쁜코드가 쌓이면 생상력이 떨어지다 0에 근접해짐.

생산성이 떨어지면 .. 인력을 더 투입해보고 .. 마침내 재설계에 돌입함.

신규 버전의 생성이 시작되면, 똑똑한 사람은 신규 프로젝트를 진행하고 나머지 사람은 기존 프로젝트를 유지보수 함. → 기존 시스템에 기능이 추가 되면 신규 프로젝트에도 추가 되야 함.

깨끗한 코드는 예술?

  • 그림 그리는 행위와 비슷
  • 그림을 보면 대부분의 사람은 잘 그렸는지 엉망으로 그려졌는지 알 수 있음 → 하지만 안다고 그림을 잘 그리는 것은 아님.. 코드도 마찬가지 → 연습을 하고 몸에 익어여 함.

깨끗한 코드?

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

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

  • Big 데이브 토마스: 깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다. 단위 테스트 케이스와 인수 테스트 케이스가 존재한다. 깨끗한 코드에는 의미 있는 이름이 붙는다. 특정 목적을 달성하는 방법은(여러 가지가 아니라) 하나만 제공한다. 의존성은 최소이며 각 의존성을 명확히 정의한다. API는 명확하며 최소로 줄였다. 언어에 따라 필요한 모든 정보를 코드만으로 명확히 표현할 수 없기에 코드는 문학적으로 표현해야 마땅하다.

  • 마이클 페더스: 깨끗한 코드의 특징은 많지만 그 중에서도 모두를 아우르는 특징이 하나 있다. 깨끗한 코드는 언제나 누군가 주의 깊게 짯다는 느낌을 준다. 고치려고 살펴봐도 딱히 손 댈 곳이 없다. 작성자가 이미 모든 사항을 고려했으므로. 고칠 궁리를 하다보면 언제나 제자리로 돌아온다. 그리고는 누군가 남겨준 코드, 누군가 주의 깊게 짜놓은 작품에 감사를 느낀다.

  • 론 제프리스: 최근 들어 나는 켄트 벡이 제안한 단순한 코드 규칙으로 구현을 시작한다. (그리고 같은 규칙으로 구현을 거의 끝낸다.) 중요한 순으로 나열하자만 간단한 코드는 다음과 같다.

    • 모든 테스트를 통ㄱ솨한다
    • 중복이 없다
    • 시스템 내 모든 설계 아이디어를 표현한다
    • 클래스, 메서드, 함수 등을 최대한 줄인다.

    물론 나는 주로 중복에 집중한다. 같은 작업을 여러 차례 반복한다면 코드가 아이디어를 제대로 표현하지 못한다는 증거다. 나는 문제의 아이디어를 찾아내 좀 더 명확하게 표현하려고 애쓴다.

    내게 있어 표현력은 의미 있는 이름을 포함한다. 보통 나는 ㄴ확정하기 전에 이름을 여러 차례 바꾼다. 이클립스와 가은 최신 개발 도구는 이름을 바꾸기가 상당히 쉽다. 그래서 별 고충 없이 이름을 바꾼다. 하지만 표현력은 이름에만 국한되지 않는다. 나는 여러 기능을 수행하는 객체나 메서드도 찾는다. 객체가 여러 기능을 수행한다면 여러 객체로 나눈다. 메서드가 여러 기능을 수행한다면 메서드 추출 리패터링 기법을 적용해 기능을 명확히 기술하는 메서드 하나와 기능을 실제로 수행하는 메서드 여러 개로 나눈다.

    중복과 표현력만 신경 써도 (내가 생각하는) 깨끗한 코드라는 목표에 성큼 다가선다. 지저분한 코드를 손볼 때 이 구가지만 고려해도 코드가 크게 나아진다. 하지만 나는 한 가지를 더 고려한다. 이는 설명하기 조금 까다롭다.

    오랜 경험 긑에 나는 모든 프로그램이 아주 유사한 요소로 이뤄진다는 사실을 깨달았다. 한 가지 예가 ‘집합에서 항목 찾기’다. 직원 정보가 저장된 데이터베이스든, 키/값 쌍이 저장된 해시 맵이든, 여러 값을 모아놓은 배열이든, 프로그램을 짜다 보면 어떤 집합에서 특정 항목을 찾아낼 필요가 자주 생긴다. 이런 상황이 발생하면 나는 추상 메서드나 추상 클래스를 만들어 실제 구현을 감싼다. 그러면 여러 가지 장점이 생긴다.

    이제 실제 기능은 아주 간단한 방식으로, 예를 들어 해시 맵으로, 구현해도 괜찮다. 다른 코드는 추상 클래스나 추상 메서드가 제공하는 기능을 사용하므로 실제 구현은 언제든지 바꿔도 괜찮다. 지금은 간단하게 재빨리 구현했다가 나중에 필요할 때 바꾸면 된다.

    게다가 집합을 추상화하면 ‘진짜’ 문제에 신경 쓸 여유가 생긴다. 간단한 찾기 기능이 필요한데 온갖 집합기능을 구현하느라 시간과 노력을 낭비할 필요가 없어진다.

    중복 줄이기, 표현력 높이기, 초반부터 간단한 추상화 고려하기. 내게는 이 세가지가 깨끗한 코드를 만드는 비결이다.

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

  • 저자(밥 아저씨): 깨끗한 변수 이름, 깨끗한 함수 이름, 깨끗한 클래스를 만들어야 한다.

우리는 저자다

코드를 읽는 시간 대 코드를 짜는 시간 비율이 10대 1이 훌쩍 넘는다. 새 코드를 짜면서 기존 코드를 끊임없이 읽는다.

보이스카우트 규칙

잘짠 코드는 시간이 지나도 언제나 깨끗하게 유지해야 한다. <- 적극 적으로 코드의 퇴보를 막아야 한다.

체크아웃 할 때보다 좀 더 깨끗한 코드를 체크인 하면 코드가 절대 나빠지지 않는다.

도서 내용 정리 - 스태프 엔지니어

개요 네이버 도서 정보:  https://bit.ly/3JzLvQr 개발자는 관리자로만 커리어를 쌓아야 하는가? 관리자가 아닌 기술 리더로 성장하는 길은 없을까? IT 업계가 계속 성장하면서 전에 없던 팀과 조직의 경계를 넘어서는 큰 문제를 다루게 되...