https://book.naver.com/bookdb/book_detail.naver?bid=7390287

 

Clean Code

로버트 마틴은 이 책에서 혁명적인 패러다임을 제시한다. 그는 오브젝트 멘토(Object Mentor)의 동료들과 힘을 모아 ‘개발하며’ 클린 코드를 만드는 최상의 애자일 기법을 정제해 책 한 권에 담았

book.naver.com

 

개념은 빈 행으로 분리하라.
종속함수는 붙이고, 개념적 유사성이 높은 함수는 가깝게 해라.

 

 

공백을 활용해라.

여기서 공백은 위에서 말했던 빈 행 같은 세로공백, 함수의 인자나 연산자를 띄우는 가로공백, 들여쓰기를 모두 의미합니다. 아래에 공백을 잘 활용한 코드와 활용하지 않은 코드를 작성했습니다.

 

public static void makeSubset(int idx,boolean[] used) {
if(idx==size) {printSubset(used);return;}
used[idx]=false;
makeSubset(idx+1,used);
used[idx]=true;
makeSubset(idx+1, used);}
public static void printSubset(boolean[] used) {
StringBuilder sb=new StringBuilder();
sb.append("{ ");
for(int i=0;i<size;i++) {
if(used[i]) {sb.append(number[i]).append(" ");}}
sb.append("}");
System.out.println(sb.toString());}

 

public static void makeSubset(int idx, boolean[] used) {
    if(idx == size) {
        printSubset(used);
        return;
    }
    used[idx] = false;
    makeSubset(idx+1, used);
    used[idx] = true;
    makeSubset(idx+1, used);
}

public static void printSubset(boolean[] used) {
    StringBuilder sb = new StringBuilder();
   
    sb.append("{ ");
   	for(int i = 0; i < size; i++) {
        if(used[i])
            sb.append(number[i]).append(" ");
    }
    sb.append("}");

    System.out.println(sb.toString());
}

 

차이가 눈에 보이시죠?

 

팀 규칙을 따르기.

아무리 자신만의 멋들어진 코딩스타일이 있다고 해도, 협업에서 남들과 다른 코딩 스타일을 사용하면 이질적인 느낌을 주겠죠. 오해를 일으킬수도 있습니다.

팀과 회사에 이미 규정된 스타일이 있다면 그것을 따르는게 가장 좋은 방법입니다.

 

728x90

https://book.naver.com/bookdb/book_detail.naver?bid=7390287

 

Clean Code

로버트 마틴은 이 책에서 혁명적인 패러다임을 제시한다. 그는 오브젝트 멘토(Object Mentor)의 동료들과 힘을 모아 ‘개발하며’ 클린 코드를 만드는 최상의 애자일 기법을 정제해 책 한 권에 담았

book.naver.com

 

 

나쁜 코드에 주석을 달지 마라.
주석은 나쁜 코드를 보완하지 못한다.
코드를 새로 짜라.

배배꼬인 스파게티 코드를 작성하고 주석으로 설명을 빙자한 변명을 단 경험이 많이 있을겁니다.

코드는 명확한 결과(성공하거나 에러를 띄우거나)를 알려주지만 주석은 아닙니다.

/* 완벽하게 잘 동작하는 코드 */ 라는 주석이 달려있다고 해서 그 코드가 정말 잘 동작할거란 보장은 없습니다.

오히려 주석을 달면서 생기는 실수로 인해 다른 프로그래머에게 오정보를 줄 수도 있습니다.

IDE는 코드의 문법상 에러는 찾아내지만 주석의 에러를 찾아내지는 못하니까요.

 

 

주석이 아니라 코드로 의도를 표현하라.
int[][] list = new int[N][3];

...

/* 직원중 1억 이상 고연봉자의 수를 세는 함수 */
for(int i = 0; i < list.length; i++){
	if(list[i][2] > 100_000_000){
    	count++;
    }
}

주석을 가리고 본다면 어떤 동작이 이루어지는지 파악하기 참 힘든 코드일겁니다.

1억이란 숫자는 무엇을 의미하는지, list 배열은 무슨 의미인지 알 수가 없습니다. 

 

Employee[] employeeList = new employeeList[N];
static int highSalary = 10_000_000;

...

for(int i = 0; i < employeeList.length; i++){
	if(employeeList[i].salary > highSalary){
    	count++;
    }
}

주석이 없지만 for문이 무슨 동작을 하는지 알수 있는 코드입니다.

적절한 이름을 통해 주석 없이도 코드를 설명할 수 있습니다.

 

 

필요한 주석

  1. 법적 권리, 저작권 라이센스 등 코드 외적인 내용을 알려주는 주석
    코드로는 설명 할 수 없는 내용을 코드 안에 표현하려면 주석밖엔 없겠죠.

  2. 경고의 의미를 담은 주석
    /*이 함수는 완료까지 8시간이 걸림*/
    /*이 작업은 주요 데이터를 삭제함*/
  3. TODO 주석
    /*어쩌구저쩌구한 기능을 구현할 곳*/

 

책에서는 좋지 않은 나쁜 주석도 알려주는데요.

너무 종류가 많아서 그냥 꼭 필요한걸 제외한 모든 주석이라고 생각하셔도 될 것 같습니다.

ㅋㅋㅋ

 

728x90

https://book.naver.com/bookdb/book_detail.naver?bid=7390287

 

Clean Code

로버트 마틴은 이 책에서 혁명적인 패러다임을 제시한다. 그는 오브젝트 멘토(Object Mentor)의 동료들과 힘을 모아 ‘개발하며’ 클린 코드를 만드는 최상의 애자일 기법을 정제해 책 한 권에 담았

book.naver.com

 

어제 예비군을 참가해서 하루 휴식(?)했습니다.

비가 온 다음날이라 습하고 덥고 난리도 아니었네요.

 

세번째 챕터는 함수입니다.

 

 

작게 만들어라.
함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다.

 

PS에서 Solution 함수를 작성할 때 우리는 항상 유혹에 부딪힙니다.

이 코드정도는 그냥 따로 빼지 않아도 되지 않을까? 

생각해 보면 제가 PS에서 함수를 쪼개는 경우는 isIn() isTrue()와 같은 조건문을 빼거나 복잡한 시뮬레이션 문제를 쪼갤때 정도였습니다. 간단한 문제라면 함수의 분리가 없어도 되겠지만 구현해야되는 코드의 수준이 복잡해질수록 함수를 쪼개는 일이 중요한걸 느끼게 됩니다.

 

함수 안의 추상화 수준을 같게 하라. 위에서 아래로 내려가라.

 

어떤 함수에서 넘겨받은 인자의 홀수/짝수 그리고 음수/양수를 판독한다고 생각해 봅시다.

간단한 조건문으로도 작성할 수 있을겁니다.

if(num % 2 == 0){
	...
}

if(num > 0){
	...
}

 

 

조건부분을 함수로 따로 분리하면 어떨까요.

이것도 보기에 나쁘지 않습니다.

if(isEven(num)){
	...
}
if(isPositive(num)){
	...
}

 

 

그럼 이런 코드는 어떨까요?

if(num % 2 == 0){
	...
}
if(isPositive(num)){
	...
}

위의 코드에선 내용이 간단하다보니 이해에 문제는 없지만, 조금 더 복잡하고 난해한 코드에선 이런 일관성을 해치는 코드가 큰 오해를 만들 수도 있습니다.

 

 

예상할 수 없는 결과를 일으키지 마라.
명령과 조회를 분리하라.

 

위에서 사용했던 isPositive() 함수를 생각해 봅시다.

다른 사람이 짠 해당 코드를 발견했고, 마침 양수를 구분해야할 필요가 있던 저는 제 개발파트에 해당 함수를 가져다 썼습니다. 그런데 알고보니 isPositive() 안이 이런코드로 구현되었다면요?

public boolean isPositive(int num){
    if(num > 0){
        answer ++;
        return true;
    }
    return false;
}

isPositive()가 호출되고 받은 인자를 양수로 판독할때마다 어딘가의 static한 변수 answer를 늘려주고 있었다면, 단순히 양수를 판독하려던 저는 프로그램을 망가트리는 치명적인 버그를 만들 수도 있습니다.

 

 

 

지키고 있던 내용도 있고, 알면서 지키지 않았던 내용도 많은 제 코드를 회고해보게 만드는 챕터였습니다.

감사합니다.

728x90

 

https://book.naver.com/bookdb/book_detail.naver?bid=7390287 

 

Clean Code

로버트 마틴은 이 책에서 혁명적인 패러다임을 제시한다. 그는 오브젝트 멘토(Object Mentor)의 동료들과 힘을 모아 ‘개발하며’ 클린 코드를 만드는 최상의 애자일 기법을 정제해 책 한 권에 담았

book.naver.com

 

두 번째 챕터입니다.

사실 그동안 PS를 하면서 편하고 익숙한 방법대로 작성한 경우가 많았습니다.

Class를 생성하지 않고 Integer 배열의 순서에 값을 집어넣는다던지, 아무 의미 없이 flag, sum, num 같은 변수명을 사용한다던지...

시간 제약이 있고 나만 보는 PS에선 큰 상관이 없을지도 모르지만 다른 사람들에게도 내 코드를 보여주어야 하는 업무상황에선 참 좋지 않은 습관이고 고쳐야겠다는 생각이 이번 챕터를 읽으면서 더 명확해졌습니다.

 

 

의도를 분명히 밝혀라.

 

list = []

이 리스트는 무슨 의미일까요?

List<> list = new ArrayList<>();

Python이 아니라 Java를 쓰면 달라질까요?

 

반복문이나 함수에서 간단하게 쓰이고 사라지는 변수여도 그 의도와 목적을 이름으로 밝힌다면 누가 보더라도 프로그래머의 의도를 파악하기 쉬워질 것입니다.

 

 

그릇된 정보를 피하라.

 

저도 자주 쓰는 알파벳이 꼭 집어 지적되어 당황했습니다.

for(int l = 0; l < L; 1++){
	if(l % 2 == O){
    	I++;
    }
}

이 코드에서 반복문의 증감자는 소문자 l이 아니라 1이고 조건문의 우항은 숫자 0이 아니라 대문자 O이고 안의 연산은 소문자 l이 아니라 대문자 I입니다.

제가 써놓고도 구분하기가 힘듭니다. 

대부분의 오탈자는 IDE에서 붉은 줄로 지적을 해주겠지만 가끔은 코드의 문법적 논리는 틀리지 않는 경우가 있습니다.

l L i I o O 앞으로는 절대로 사용을 지양하겠습니다. 

 

의미있게 구분하라.

 

학생 N명의 언수외탐 네 가지 점수를 저장해야 하는 문제를 풀 때 어떻게 구현할까요?

가장 손쉬운건 int[][] grade = new int[N][4]; 따위의 2차원 배열을 만드는 것일 겁니다.

하지만 grade가 점수라는 건 알 수 있어도 각 원소의 첫 번째 값과 두 번째 값의 의미는 사라져 버립니다.

사전 지식 없이 grade[n][0]이 언어 점수이고 grade[n][1]이 수리 점수라는 걸 추측할 수 있는 사람은 없을 겁니다.

 

따로 객체를 만든다면 어떨까요?

public class Grade{
    int korean;
    int math;
    int english;
    int science;
    ...
    
    int getKorean(){
    	return this.korean;
    }
    ...
}

 

Grade[] grade = new Grade[N];

grade[n].korean 혹은 grade[n].getKorean()라는 코드를 본다면 못해도 90% 이상의 프로그래머는 언어 점수를 의미한다는 걸 알 수 있을 겁니다.

 

또 메소드명을 getKorean(), setKorean(), isKorean(), passKorean() 같은 식으로 일관성 있게 작성한다면 한 달, 1년이 지나도 코드를 다시 봤을 때 이해하기가 쉬울 겁니다.

 

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

 

IDE가 발전하면서 검색, 치환 같은 기능을 사용할 일이 무척 많습니다.

검색이 쉽다는 건 코드의 구조를 이해하기도 쉽다는 뜻이고, 검색이 쉽다는건 변수명이 바뀌거나 수정이 필요한 경우 찾아가기도 쉽다는 것입니다.

 

의미 있는 맥락을 추가하고 불필요한 맥락을 없애라.

 

RPG 게임을 만든다고 합시다.

이름은 코드킹의 전설 쯤이 좋겠네요. 영어로는 Legend of Codeking이 되겠습니다.

이제 이 게임 안에서 플레이어의 정보를 담은 객체를 만드려고 합니다.

코드킹의 전설 속 플레이어니까 LOC_Player로 작성했습니다.

만약 접두어 LOC_가 없다면 우리가 이 Player 객체가 어느 게임에서 쓰이는지를 모를까요?

게임이 여러 개 묶여있는 개발 형태라면 몰라도 당연한 맥락을 프로그래머의 손가락을 써가며 덧붙여 치는 건 낭비입니다.  

덧붙여서 IDE를 사용한다면 후자는 P만 눌러도 인텔리센스로 Player를 자동완성할 수 있겠지만, 전자는 L을 누른다면 LOC_Player, LOC_Item, LOC_Monster... 따위의 자동완성이 무분별하게 제공될 겁니다.

 

생산성을 위해서도 맥락은 꼭 필요한 것만! 

728x90

https://book.naver.com/bookdb/book_detail.naver?bid=7390287 

 

Clean Code

로버트 마틴은 이 책에서 혁명적인 패러다임을 제시한다. 그는 오브젝트 멘토(Object Mentor)의 동료들과 힘을 모아 ‘개발하며’ 클린 코드를 만드는 최상의 애자일 기법을 정제해 책 한 권에 담았

book.naver.com

 

클린 코드. 유명하고 프로그래머라면 정말 많이 추천받는 책입니다.

 

저도 아마 대학을 졸업했을 즈음 추천을 받아 구입했는데요.

사놓고 제대로 정독한 적이 없는 것 같아서 매일 1 챕터씩 정리하면서 읽어보려고 합니다.

너무 자세한 내용을 적으면 책의 저작권을 침해하니까요. 중요한 키워드와 Inspiration을 준 문구들을 위주로 제가 가진 경험과 함께 정리해보려고 합니다.

 

 

 

나쁜 코드가 쌓일수록 생산성은 떨어진다. 그러다가 마침내 0에 근접한다.

 

프로그래밍을 할때 자주 쓰는 말이 있습니다.

 

"이게 왜 되지?" 그리고 "이게 왜 안되지?"

 

간단히 생각하면 전자는 원하는 목표에 도착했다는 것이고 후자는 목적을 달성하는데 실패했다는 얘기입니다.

하지만 실제로 저런 상황을 맞이했을 때, 후자의 경우가 디버깅을 통해 문제를 찾기가 더 쉽습니다.

처음부터 접근을 잘못한게 아니라면 버그가 발생한 코드를 찾아 고칠 수 있습니다.

반면 전자는 당장은 코드가 돌아갈지 몰라도 예외 케이스에 걸리거나 이후 다른 문제가 발생했을 때 난감한 상태가 되는 일이 많았습니다.

 

블로그에 포스팅을 작성하면서 예전에 제가 썼던 코드를 보고 수정하는 일이 많은데 제가 쓴 코드이다보니 어지간하면 이해가 되지만 가끔 무슨 생각으로 짠 거지? 싶은 코드들이 있습니다. 

코드를 짠 장본인도 이해하지 못하는 코드를 동료, 상사, 고객들이 이해하길 바라는건 욕심이겠죠.

 

 

 

잘못은 전적으로 프로그래머에게 있다. 우리가 전문가 답지 못했다.

 

책의 부연설명을 조금 덧붙이면, 요구사항이나 기획이 아름답지 못할때 그것을 지적하고 고치는 것도 프로그래머의 일이라는 얘기였습니다.

저도 프로젝트를 진행할 때 기획이 여러번 엎어지거나 FE와 BE간에 명세서나 API 문서를 작성하면서 충돌했던 경험이 있습니다. 왜 그렇게 기능을 개발할 수 없는지, 왜 이런 방식으로 코드를 짜는지 설득하려면 내 코드가 그만큼 깔끔하고 정확해야 하겠죠.

 

 

논리가 간단해야 버그가 숨어들지 못한다.

 

PS를 할 때 많이 체감되는 문구입니다.

문제를 보고 떠오른 풀이방법대로 코드를 작성하는 경우가 억지로 예외사항과 조건을 좁혀가며 코드를 작성하는 경우보다 더 정확한 일이 많았습니다.

당연히 버그가 생겼을때 수정하기도 더욱 쉬웠습니다.

 

 

중복을 피하라. 한 기능을 수행하라. 제대로 표현해라. 작게 추상화해라.

 

 

 

클린 한 코드가 왜 필요한지, 왜 써야 하는지 동기를 부여하는 1장이었습니다.

다음 2장은 코드에서 "이름"을 잘 사용하는 방법에 대한 내용이 진행됩니다.

 

 

728x90

+ Recent posts