팀으로 일한다면 그 규칙을 따라야 한다.

형식을 맞추는 목정

코드 형식은 의사소통의 일환이다. 오늘 구현한 코드는 변경될 가능성이 높다.

이 과정에서 코드는 변경되어도 처음에 잡아둔 코드 형식은 남아 유지보수 용이성과 확장성에 영향을 미친다.

 

코드는 사라져도 스타일과 규율은 사라지지 않는다.

 

적절한 행 길이를 유지하라

대부분 프로젝트의 코드는 500줄을 넘지 않고 최빈도는 200줄 미만이다.

즉, 200~500줄 코드로도 커다란 시스템을 구축할 수 있다.

반드시 지켜야 할 엄격한 규칙은 아니지만 바람직한 규칙이다.

일반적으로 큰 파일보다 작은 파일이 이해하기 쉽다.

 

 

 

신문 기사처럼 작성하라

좋은 신문 기사는 최상단에 기사를 몇 마디로 요약하는 표제가 나온다.

독자는 표제를 보고서 기사를 읽을지 말지를 결정한다.

 

첫 문단은 전체 기사 내용을 요약한다.

세세한 사실은 숨기고 커다란 그름을 보여준다.

쭉~ 읽으며 내려가면 세세한 사실이 조금씩 드러난다.

 

소스 파일도 신문기사와 비슷하게 작성한다.

이름은 간단하면서 설명이 가능하게 짓는다. 이름만 보고 올바른 모듈을 살펴보는지 판단할 수 있어야 한다.

소스 파일 첫 부분은 고차원 개념과 알고리즘을 설명한다.

아래로 갈수록 세세하게 묘사한다. 가장 마지막에는 가장 저 차원 함수와 세부 내역이 나온다.

 

 

개념은 빈행으로 분리하라

각 행은 수식이나 절이고 일련의 행 묶음은 완결된 생각 하나이다.(메서드)

생각 사이는 빈행을 넣어야 한다. 

 

 

세로 밀집도

줄 바꿈이 개념을 분리한다면 세로 밀집도는 연관성을 의미한다.

즉, 서로 연관된 코드는 가까이 위치해야 한다.

 

 

수직 거리

함수 연관 관계와 동작 방식을 이해하려고 스크롤을 드르륵드르륵 거린 적 있는가?

서로 연관된 코드는 수직 거리가 가까워야 한다.

서로 밀접한 개념은 한 파일에 속해야 마땅하다.

클래스를 뒤적거리는 것은 안 좋다.

 

인스턴스 변수 클래스 처음에 선언하고 변수 간에 세로로 거리를 두지 않는다.

가장 중요한 것은 인스턴스 변수들은 클래스 앞에 뭉쳐있어야한다.

 

종족 함수

한 함수가 다른 함수를 호출한다면 세로로 가까이 배치한다.

가능하면 호출하는 함수를 호출되는 함수보다 먼저 배치한다.

 

개념적 유사성

친화도가 높을수록 코드를 가까이 배치한다.

함수가 다른 함수를 호출해 생기는 직접적인 종속성이 친화도가 높은 예시다.

변수와 변수를 사용하는 함수도 좋은 예시다.

세로 순서

함수 호출 종속성은 아래방향으로 유지된다. , 호출하는 함수부터 오고 호출되는 함수가 아래에 배치된다

따라서 자연스럽게 고차원함수가 위에 저차원함수가 아래에 배치된다.

이는 다른 개발자가 소스 파일에서 함수 개만 읽어도 개념을 파악하기 쉬워진다. 세세한 사항까지 파고들 필요가 없다.

 

가로 형식 맞추기

100~120 수준이 적당

 

가로 공백과 밀집도

가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한다

들여 쓰기

범위(scope) 이뤄진 계층을 표현하기 위해 우리는 코드를 들여쓴다.

들여 쓰는 정도는 계층에서 코드가 자리잡은 수준에 비례한다.

규칙

규칙이 우선이다. 각자의 스타일이 먼저가 절대 아니다. 일관성이야 말로 좋은 가독성을 보장한다.

 

 

 

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

7장 오류 처리  (0) 2022.10.12
6장 객체와 자료 구조  (1) 2022.10.06
4장 주석 - 나쁜 주석  (1) 2022.10.01
4장 주석 - 좋은 주석  (0) 2022.09.28
3장 함수 - 2  (2) 2022.09.25

대다수의 주석이 이 범주에 속한다.

허술한 코드를 지탱하거나, 엉성한 코드를 변명하거나, 미숙한 결정을 합리화하는

 

주절거리는 주석

특별한 이유 없이 의무감으로 다는 주석

의미를 파악하려면 결국 코드를 뒤져보는 수밖에 없다.

주석을 달기로 했다면 충분한 시간을 들여 최고의 주석을 달도록 노력한다.

오해할 여지가 있는 주석

의무적으로 다는 주석

모든 함수에 Javadocs 달거나 모든 변수에 주석을 달아야 한다는 규칙은 어리석기 그지없다.

이런 주석은 코드를 복잡하게 만들며, 거짓말을 퍼뜨리고, 혼동과 무질서를 초래한다.

이력을 기록하는 주석

이력을 관리하는 주석은 없애버리는 좋다. 이제는 소스코드 관리시스템이 있기 때문이다.

공로를 돌리거나 저자를 표시하는 주석도 소스코드관리시스템에 맡기는 게좋다.

주석으로 처리한 코드도 소스코드관리시스템에 맡긴다.

 

있으나 마나 주석

쉽게 말해, 너무 당연한 사실을 언급하며 새로운 정보를 제공하지 못하는 주석

이런 주석은 개발자가 주석을 무시하는 습관에 빠지게 할 수도 있다.

있으나 마나 주석을 달려는 유혹에서 벗어나 코드를 정리하라.

 

함수나 변수로 표현할 있다면주석을 달지 마라

위치를 표시하는 주석

때때로 프로그래머는 소스 파일에서 특정 위치를 표시하려 주석을 사용한다.

// 수정필요///////////////////////////////////////////

일반적으로 위와 같은 주석은 가독성만 낮추므로 제거해야 마땅하다.

특히, 뒷부분 슬래시(/) 주석은 최악이다.

 

 

닫는 괄호에 다는 주석

중첩이 심하고 장황한 함수라면 의미가 있을지도 모르지만,

우리가 선호하는 작고 캡슐화된 함수에는 잡음일 뿐이다.

그러므로 달아야겠다는 생각이 든다면 함수를 줄이려 시도하자

요즘은  IDE 괄호 파악을 잘해줘서 더욱 불필요할

try{
	while(true){
    	...
    }//while 끝
	...
}//try 끝

 

공로를 돌리거나 저자를 표시하는 주석

소스 코드 관리 시스템은 누가 언제 무엇을 추가했는지 귀신처럼 기억한다.

저자 이름으로 코드를 오염시킬 필요가 없다.

주석이 있으면 다른 사람이 물어볼 있으니 유용하다 생각할지 모르겠다.

하지만 현실적으로 이런 주석은 그냥 오랫동안 코드에 방치되어 점차 부정확하고 쓸모없는 정보로 변하기 쉽다.

그냥 소스 코드 관리 시스템에 맡기는 편이 옳다.

 

주석으로 처리한 코드

주석으로 처리된 코드는 다른 사람들이 지우기를 주저한다.

이유가 있어 남겨놓았으리라고, 중요하니까 지우면 안된다고 생각한다.

결국 쓸모 없는 코드가 점차 쌓여간다.

 

1960년대 즈음에는 주석으로 처리한 코드가 유용했었다. 하지만 우리는 오래전부터 우수한 소크 코드 관리 시스템을 사용해왔다. 소스 코드 관리 시스템이 우리를 대신해 코드를 기억해준다. 이제는 주석으로 처리할 필요가 없다. 그냥 코드를 삭제하라. 잃어버릴 염려는 없다. 약속한다.

 

너무 많은 정보

너무 많은 정보를 다는 주석은 않좋다.

모호한 관계

주석과 주석이 설명하는 코드는 사이 관계가 명백해야 한다.

이왕 공들여 주석을 달았다면 적어도 독자가 주석과 코드를 읽어보고 무슨 소린지 알아야 하지 않겠는가?

 

함수 헤더

짧은 함수는 설명이 필요 없다.

짧고 가지만 수행하며 이름을 붙인 함수가 주석으로 헤더를 추가한 함수보다 훨씬 좋다.

 

 

비공개 코드에서 Javadocs

공개 API Javadocs 유용하지만 공개하지 않을 코드라면 Javadocs 쓸모가 없다.

시스템 내부에 속한 클래스와 함수에 Javadocs 생성할 필요는 없다.

유용하지 않을 뿐만 아니라 Javadocs주석이 요구하는 형식으로 인해 코드만 보기 싫고 산만해질 뿐이다.

 

 

 

 

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

6장 객체와 자료 구조  (1) 2022.10.06
5장 형식 맞추기  (0) 2022.10.05
4장 주석 - 좋은 주석  (0) 2022.09.28
3장 함수 - 2  (2) 2022.09.25
3장 함수 - 1  (0) 2022.07.05

주석은 순수하게 선하지 못하다. 주석은 필요악이다.

프로그래밍 언어 자체가 표현력이 풍부하다면, 우리가 치밀하게 프로그래밍하면 안 쓸 수도 있기 때문이다.

주석은 우리가 코드로 의도를 표현하지 못해서 사용하는 것이다.

따라서 주석을 쓰기 전에 코드로 표현할 수 없을 지를 고민하자

 

주석은 거짓말을 한다. 현실적으로 프로그래머가 주석은 관리하고 최신화하지 않기 때문이다.

따라서 코드가 시간이 지남에 따라 거듭 변경되면 될 수록 코드와 주석은 점점 멀어진다.

아니, 분리된다.

 

거짓말하는 주석은 없는 주석보다 더 나쁘다.

 

반면에 코드를 보자, 코드는 항상 진실된 정보만 제공한다.

주석은 나쁜 코드를 보완하지 못한다.

코드에 주석을 추가하는 일반적인 이유는 코드 품질이 나쁘기 때문이다.

표현력이 뛰어나며 주석이 거의 없는 코드가, 복잡하고 어수선하며 주석이 많이 달린 코드보다 좋다.

 

코드로 의도를 표현하라

// 보너스 받을 자격을 검사한다.
if(employee.performance == "우수" && employee.age <=30)  //이런 것보다.
if(employee.isBenefit())  // 이게 가시성이 우수하다.

좋은 주석

좋은 주석은 글자 값을 한다.

하지만 명심하라! 정말로 좋은 주석은, 주석을 달지 않을 방법을 찾아낸 주석이라는 사실을!

 

법적인 주석

저작권 정보, 소유권 정보 등은 필요하고 타당한 주석이다.

 

정보를 제공하는 주석

abstract 메서드의 경우 나중에 구현부가 될 정보를 알려준다.

의도를 설명하는 주석

구현이 조금 복잡하다면 이해를 도와주는 선을 넘어 의도를 설명하는 것도 나쁘지 않다

의미를 명료하게 밝히는 주석

때때로 모호한 인수나 반환값은 의미를 읽기 좋게 포현하면 이해하기 쉬워진다.

인수나 반환값 자체를 명확히 하면 좋겠지만,

인수나 반환값이 라이브러리나 변경하지 못하는 코드에 속한다면 의미를 명료하게 밝히는 주석이 유용하다

결과를 경고하는 주석(특히 테스트 케이스에서)

// 테스트 시간이 오래 걸립니다. 주의하세요!
public void _somethingTest(){
....

물론 요즘에는 @Ignore 속성을 이용해 테스트 케이스를 꺼버린다.

구체적인 설명은 @Ignore속성에 문자열로 넣어준다.

@Ignore("실행이 너무 오래 걸린다.")

JUnit4 나오기 이전에는 메서드 이름 앞에 _ 기호를 붙이는 관례가 있었다.

 

TODO 주석

TODO주석은 당장 구현하기 어려운 업무를 기술한다.

예를 들어 누군가에게 문제를 봐달라는 요청, 앞으로 발생할 이벤트에 맞게 고치라는 등등…

TODO주석은 IDE기능을 사용해 주기적으로 검사해서 제거해 나가야 한다.

 

중요성을 강조하는 주석

정말 중요한 정보를 강조하기 위함

공개 API에서 Javadocs

설명이 공개 API 유용하고 만족스럽다.

표준 자바 라이브러리에서 사용한 Javadocs 좋은 예다.

자바 독이없다면 개발이 어려울

이처럼 공개 API 구현한다면 반드시 훌륭한 Javadocs 작성한다.

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

5장 형식 맞추기  (0) 2022.10.05
4장 주석 - 나쁜 주석  (1) 2022.10.01
3장 함수 - 2  (2) 2022.09.25
3장 함수 - 1  (0) 2022.07.05
2장 의미 있는 이름  (0) 2022.07.01

서술적인 이름을 사용하라

함수가 하는 일을 좀 더 잘 표현하기

코드를 읽으면 짐작했던 기능을 수행한다면 좋은 이름이다.

이름이 길어도 두려워하지 말라, 길고 서술적인 이름이 짧고 어려운 이름보다 좋다.

특히, 길고 서술적인 이름이 길고 서술적인 "주석"보다 좋다.

요즘은 IDE 기능을 이용하면 이름 변경이 쉬우므로 자주 변경하는 것에 두려워할 필요 없다.

 

 

 

함수 인수

함수에서 가장 이상적인 인수 개수는 0 개다.

다음은 단항, 다음은 이항이다.

 

인수는 함수 개념을 이해하기 어렵게 한다.

인수가 있다면 내부구조를 봐서 무슨 일을 하는지 세부사항을 확인해야 한다.

 

또한 테스트 관점에서 함수 인수는 테스트를 더욱 어렵게 한다.

인수가 3개 이상이라면 모든 경우의 수를 테스트하기 힘들어진다.

인수가 없다면 쉬울 것이다.

 

인수가 두 개 이상부턴 인수의 순서도 생각해야 한다.

 

결과적으로 최선은 인수가 없는 것이고, 차선은 인수가 1개인 것이다.

 

 

많이 쓰는 단항 형식

  • 인수에 질문을 던지는 경우
    boolean fileExists("file")
  • 인수를 뭔가로 변환해 결과를 반환하는 경우
    InputStream fileOpen("file")

위와 같은 경우가 아니라면 단항 함수도 가급적 피하는 것이 좋다

인수를 무언가로 변환하는 함수의 경우 이름을 명확히 해야 한다.

좋은 예시

Integer parseInt()  

딱 봐도 반환 결과가 Integer 형일 것을 알 수가 있다.

 

 

 

플래그 인수

플래그 인수는 추하다. 함수로 boolean 값을 넘기는 것은 끔찍하다.

함수는 한 가지만 잘해야 하는데, 플래그 인수가 true/false에 따라 동작을 달리한다는 것은 SRP를 위배한다. 

또한, 외부에서 값을 받아 객체가 조작된다는 것은 의존성이 높다는 것과 같다.

차라리 함수를 두 개로 쪼개는 것이 올바르다.

 

 

이항 함수

이항 함수부터는 인수 순서에도 주의가 필요하다.

가급적 안 쓰는 것이 좋지만, 문맥상 자연스러운 이항 함수도 분명 존재한다.

compare(a, b) ,  Objects.equeals(a, b)...

 

 

삼항 함수

당연히 이항 함수보다 훨씬 이해하기 어렵다.

순서, 주춤, 무시로 야기되는 문제가 이상 늘어난다.

 

인수 객체

인수가 많아 일부를 독자적인 인수 객체로 선언한 경우

인수 객체가 단순히 인수 개수를 줄이겠다는 눈속임으로 생각할 수 있다.

꼭 그렇지만은 않다. 인수 사용 시 객체의 이름을 꼭 붙여야 하므로 결국 개념을 표현하게 된다.

 

 

동사와 키워드

함수 인자 이름과 함수 이름은 명사/동사 쌍을 이루면 좋다.

find(item)  누가 봐도 아이템을 찾는 것이라는 것을 알 수 있다.

더 좋은 방향은 인수 순서까지 표시하는 것이다.

inputPasswordEqualsDbPassword(intputPassword, DbPassword)

 

 

부수 효과를 일으키지 마라

부수효과는 거짓말이다. 함수는 한 가지만 하겠다고 약속하고선 남몰래 다른 짓도 하니까.

클래스 변수나, 참조 변수를 수정하면, 많은 경우 시간적인 결합이나 순서 종속성을 초래한다.

특히, 부수효과를 파악하려면 함수 내부를 들여봐야지만 알 수가 있다.

따라서 어쩔 수 없는 경우는 함수 이름으로 부수효과를 알 수 있게 해야 한다.

 

 

출력 인수

appendFooter(String str)

이 함수를 호출하는 쪽 관점에서 보자.

이 함수를 호출하면 str을 바닥글로 첨부하는 것일까? 아니면, str에 바닥글을 첨부할까?

알 수가 없어 이 함수를 호출한 선언부를 찾아본다.

이는 코드를 보다가 주춤하는 행위와 동급이다. 인지적으로 거슬리므로 피해야 한다.

 

객체지향 언어에서는 출력 인수를 사용할 필요가 거의 없다. 출력 인수를 사용하라고 설계한 변수가 this이기 때문이다.

 

 

명령과 조회를 분리하라

함수는 무언가를 수행하거나 무언가에 답하거나 둘 중 하나만 해야 한다.

객체 상태를 변경하거나, 객체 정보를 반환하거나   

위 두 행위를 하나의 함수로 하는 경우를 보자

public boolean set(String attribute, String value)

이 함수는 이름이 attribute인 속성을 찾아 값을 value로 설정하고 결과를 boolean으로 리턴한다.

set("username", "kks") 

이 경우 username 속성을 찾아 kks로 설정에 성공한 결과를 반환하는 것인지

username 속성에 kks 값이 존재할 때 결과를 반환하는 것인지 모호하다.

 

함수 이름을 명확히 해 분별이 가능하게 할 수도 있지만, 애초에 명령과 조회를 분리해 혼란을 뿌리 뽑는 것이 좋다.

attributeExists("username")  조회

setAttribute("username", "kks")  명령

 

 

 

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

명령 함수에서 오류 코드를 반환하는 방식은 명령/조회 분리 규칙을 미묘하게 위반한다.

오류 코드 대신 예외를 사용하면 오류 처리 코드가 원래 코드에서 분리되므로 코드가 깔끔해진다.

 

 

 

Try/Catch 블록 뽑아내기

원래 try/catch 블록은 추하다. 코드 구조에 혼란을 일으키며, 정상 동작과 오류 처리 동작을 뒤섞는다.

그래서 try/catch 블록을 별도 함수로 뽑아내는 편이 좋다.

	void method1() {
		try {//정상 동작
			something1();
			something2();
			something3();
		}catch (Exception e){
			//오류 처리 동작
		}
		
	}
    
    /**********************************/
    //try/catch 블록 뽑아내기
	void tryCatch(){
		try {
		method1();
		}catch (Exception e) {
			//오류 처리만 한다.
		}
	}
	
	void method1() throws Exception{
		//정상 동작만 한다.
		something1();
		something2();
		something3();
		
	}

 

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

, 함수는 가지일만 한다는 원칙에 부합해야 한다.

따라서 오류처리를 하는 함수는 오류처리만 해야한다.

 

 

 

오류 코드 대신 예외를 사용하자

예를 들어, Error enum 클래스가 있다고 하자, 이 열거형 클래스가 변경되는 순간

열거형 클래스를 사용하는 곳 모두 컴파일을 다시 해야 한다.

그래서 Error enum 클래스를 변경하기 어려워진다.

반면에 오류 코드 대신 예외를 사용하면 재컴파일/재배치 없이도 새 예외 클래스를 추가할 수 있다.

 

반복하지 마라

중복은 문제이다. 코드 양이불필요하게 늘어나며 수정하고 싶다면 중복된 부분을 전부수정해야 한다. 또한 조금씩 상이한 부분이 생기면 유지보수가 더 힘들어진다.

중복은 가장 악이다

많은 원칙과 기법이 중복을 없애거나 제어할 목적으로 나왔다.

객체지향에서는 코드 중복을 부모 클래스로 몰아 없앤다.

구조적 프로그래밍, AOP, COP(Component Oriented Programming) 중복을 제거하기 위한 전략이다.

소프트웨어 개발에서 지금까지 일어난 혁신은 소크 코드에서 중복을 제거하려는 지속적인 노력으로 보인다.

 

함수를 어떻게 짜죠?

글짓기와 비슷하다. 먼저 생각을 기록한 읽기 좋게 다듬는다.

함수도 처음에는 길고 복잡하다. 들여 쓰기 단계도단계도 많고 중복된 루프도 많다. 인수 목록도 아주 길다. 이름은 즉흥적이고 코드는 중복된다. 이렇게 서투른 코드를 빠짐없이 테스트하는 단위 테스트 케이스를 만든다.

그런 다음 코드를 다듬고, 함수를 만들고, 이름을 바꾸고, 중복을 제거하고, 메서드를 줄이고 순서를 바꾼다. 때로는 전체 클래스를 쪼개기도 한다. 모든 과정에도 항상 단위 테스트를 통과한다.

누구도 처음부터 짜는 코드란 없다.

 

 

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

4장 주석 - 나쁜 주석  (1) 2022.10.01
4장 주석 - 좋은 주석  (0) 2022.09.28
3장 함수 - 1  (0) 2022.07.05
2장 의미 있는 이름  (0) 2022.07.01
1장 깨끗한 코드  (0) 2022.06.27

프로그램에서 가장 기본적인 단위가 함수다.

함수를 잘 만드는 방법을 알아보자

작게 만들어라

작게 더 작게!

책의 저자는 근거를 대기는 어렵지만 40년간 경험과 시행착오를 바탕으로 작은 함수가 좋다고 주장한다.

 

블록과 들여 쓰기

함축적으로 말하면 제어문이나 반복문 등에 들어가는 블록 속 코드는 한 줄이여야 한다는 의미다.

따라서 그 안에서 함수를 호출하게 된다. 그리고 그 함수 이름을 잘 짓는다면 코드를 이해하기도 쉬워진다.

public class Ex01 {
	public static void main(String[] args) {
		int number = 31;
		
		if(isEvenNumber(number) ) {
			reportEvenNumber();
		} else {
			reportOldNumber();
		}
		
	}

	private static void reportOldNumber() {
		System.out.println("홀수에요!!");
	}

	private static void reportEvenNumber() {
		System.out.println("짝수에요!!");
	}
	private static boolean isEvenNumber(int number) {
		return number%2 == 0 ? true : false;
	}
}

블록과 들여 쓰기는 1단이나 2단을 넘어서면 안 된다. 중첩 구조가 생길만큼 커지면 안된다.

 

 

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

함수내에 추상화 수준을 섞으면 코드를 읽는 사람이 헷갈린다.

특정 표현이 근본 개념인지 세부사항인지 구분하기 어렵고 섞이기 시작하면 깨진 창문 효과 처럼 사람들이 함수에 세부사항을 점점 추가한다.

 

 

위에서 아래로 코드 읽기: 내려가기 규칙

코드는 위에서 아래로 잘 쓴 글처럼 읽혀야 된다.

위에 함수는 추상화 수준이 높다.

아래 함수는 추상화 수준이 낮다.

위에서 아래로 갈수록 추상화 수준이 한 단계 씩 낮아진다.

 

 

Switch 문은 작게 만들기 어렵다. ( if/else 포함)

public Money calculatePay(Employee e) throws InvalidEmployeeType {
	switch (e.type){
		case COMMISSIONED:
			return calculateCommissionedPay(e);
		case HOURLY:
			return calculateHourlyPay(e);
		case SALARIED:
			return calculateSalariedPay(e);
		default:
			throw new InvalidEmployeeType(e.type);
	}
}

위 함수의 문제점

  1. 함수가 길다. 새 직원 유형 추가 시 더 길어진다
  2. 함수는 한 가지 작업을 잘해야 한다. 위 함수는 한 작업만 수행하지 않는다.
  3. SRP(Single Responsibility Principle) 위반한다. 코드를 변경할 이유가 여럿이다.
  4. OCP(Open Closed Principle) 위반한다. 새 직원 유형 추가 때마다 코드를 변경한다.
public abstract class Employee {
	public abstract boolean isPayday();
	public abstract Money calculatePay();
	public abstract void deliverPay(Money pay);

}
 #########################
interface EmployeeFactory {
	public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
}
#########################
public class EmployeeFactoryImpl implements EmployeeFactory {

	@Override
	public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
		switch (r.type) {
		case COMMISSIONED:
			return new CommissionedEmployee(r);
		case HOURLY:
			return new HourlyEmployee(r);
		case SALARIED:
			return new SalariedEmployee(r);
		default:
			throw new InvalidEmployeeType(r.type);
		}
	}
}

switch문을 추상 팩토리에 숨겼다. 팩토리에서 적절한 Employee 구현체 인스턴스를 반환한다. 

반환된 객체는 다형성을 통해 서로 다른 동작을 하게 된다.

 

 

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

4장 주석 - 나쁜 주석  (1) 2022.10.01
4장 주석 - 좋은 주석  (0) 2022.09.28
3장 함수 - 2  (2) 2022.09.25
2장 의미 있는 이름  (0) 2022.07.01
1장 깨끗한 코드  (0) 2022.06.27

사소해 보이지만 가장 쉽고  중요하다.

이름은 변수, 함수, 인수, 클래스, 패키지, 소스파일, jar, war... 어디에나 붙는다.

 

요즘은 IDE발전으로 일괄 이름 바꾸기가 편하다. 따라서 크게 고민하지 말고 주저 없이 이름을 붙여라

 

의도를 분명히 밝혀라

좋은 이름을 지으려면 시간이 걸리지만 그보다 좋은 이름으로 절약하는 시간이 더 크다.

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

 

그릇된 정보를 피하라

헛갈릴만한 약어 사용을 피하라. 독자에게 그릇된 정보를 제공한다.

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

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

 

 

의미있게 구분하라

불용어 사용을 피하자. 아무런 정보를 주지 못한다.

내가 만약 계좌 정보 알려주는 메서드를 찾는다. 한 클래스에 다음과 같이 메서드가 존재한다. 도대체 무엇을 호출해야 하는가?

getActiveAcount();
getActiveAccounts();
getActiveAccountInfo();

누가 봐도 의미를 파악할 수 있게 구분하자.

 

 

 

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

발음이 어려운 이름을 사용하면 상호 커뮤니케이션이 어려워진다.

int zkaq ; // 엑스케이이이큐에 값을 저장하면되요!
int sum ;  // 썸에 값을 저장하면 되요!

 

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

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

내가 상수로 지정한 MAX_CLASSES_PER_STUDENT 찾기 쉬울까?

해당 상수의 값인 7 찾는 것이 찾기 쉬울까?

특히 한자리 변수는 찾기 어렵다. 이런 관점에서 이름이 짧은 이름보다 좋다. 검색하기 쉬운 이름이 상수보다 좋다.

 

 

인코딩을 피하라

과거 코딩할 때나 필요했던 정보

자바는 강타입 언어라 필요 없다.

 

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

문자 하나만 사용하는 변수 이름은 문제가 있다. 간단한 for 문에서 사용하는 i,j..등은 괜찮지만 나머지 상황에서는 누가봐도 명확하게 이름을 지어야 한다.

전문가 프로그래머는 자신의 코드를 남들이 최대한 이해하기 쉽게 한다.

 

 

클래스 이름

클래스 이름은 일반적으로 명사나 명사구를 사용하고, 동사는 피한다

Manager,Processor,Data,Info 등과 같은 모호한 단어는 피한다.

 

메서드 이름

메서드 이름은 동사나 동사구를 사용하자

접근자, 변경자, 조건자는 자바빈 규약에 따라 set, get, is 붙이자.

 

 

기발한 이름은 피하라

재미난 이름보다 명료한 이름을 선택하라

의도를 분명하고 솔직하게 표현하라

 

 

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

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

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

메서드 이름은 독자적이고 일관적이어야 한다. 그래야 주석을 뒤져보지 않고도 프로그래머가 올바른 메서드를 선택한다.

 

 

말장난을 하지마라

단어를 가지 목적으로 사용하지 마라. 다른 개념에 같은 단어를 사용하는 것은 말장난에 불과하다.

 

add 더하기로 사용했는데 다른 클래스나 메서드에서 집합에서 추가의 뜻으로 add 사용하면 옳은 것인가? 이럴때는 insert, append 사용하라

 

프로그래머는 코드를 최대한 이해하기 쉽게 짜야 한다. 주의깊게 봐야 이해가능한 코드가 아니라 대충 훑어봐도 이해할 코드 작성이 목표다.

 

 

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

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

예를 들어, Factory 패턴을 사용했다면 CustomFactory 이런식

 

 

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

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

 

의미 있는 맥락을 추가하라

클래스, 함수, 이름 공간에 맥락을 부여하자.

street, city ,state, zipcode 라는 변수가 있을때

훑어보면 맥락상으로 주소라는 것을 있다.

허나 단순히 하나의 변수만 사용할때 state 사용한다고 이게 주소인지 확실히 있을까?

이럴때 접두사를 붙인다 addrStreet, addrCity, addrState, addrZipcode

좋은 방법은 클래스로 묶는 것이다. Address 클래스를 만들고 멤버로 추가하자

 

 

불필요한 맥락을 없애라

의미가 분명한 경우에 한해서 짧은 이름이 이름보다 좋다. 이름에 불필요한 맥락을 추가하지 않도록 주의하자.

 

마치면서

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

대부분 사람은 자신이 클래스, 메서드 이름을 모두 암기하지 못한다.

이부분은 개발도구에 맡기고 개발자는 자료 구조처럼 읽히는 코드를 짜는데 집중해야한다.

이름을 자신 나름대로 바꿨다고 질책받았다고 해서 포기하면 안된다.

요즘은 IDE에서 쉽게 이름을 일괄로 바꿀 있기 때문에 좋은 이름이 생각나면 주저 없이 바꾸

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

4장 주석 - 나쁜 주석  (1) 2022.10.01
4장 주석 - 좋은 주석  (0) 2022.09.28
3장 함수 - 2  (2) 2022.09.25
3장 함수 - 1  (0) 2022.07.05
1장 깨끗한 코드  (0) 2022.06.27

코드가 존재하리라

코드는 요구사항을 상세히 표현하는 수단이다.

어느 정도 수준에 이르면 코드의 도움 업싱 요구사항을 상세하게 표현하기란 불가능하다.

궁극적으로 코드는 요구사항을 표현하는 언어라는 사실을 명심한다.

 

 

나쁜 코드

우리는 나쁜 코드를 본적도 짠 적도 있을 것이다.

우리 모두는 자신이 쓰레기 코드를 나중에 손보겠다고 생각한 경험이 있다. 하지만 나중은 결코 오지 않는다.

 

 

나쁜 코드로 치르는 대가

프로젝트 초반에 코드에 시간은 안쓰고 대충 짠 나쁜 코드를 빠르게 치고 나가는 경우가 있다.

하지만 조금만 지나면 뮨재가 생긴다. 코드를 고칠 때 마다 엉뚱한 곳에 문제가 생기고 코드 변경이 어려워진다.

결국 나쁜 코드가 쌓여 생산성이 저하된다.

 

 

원대한 재설계의 꿈

기존 코드가 엉망이라 생산성이 안나와 관리층에서 재설계를 허용해 줘도 결국 재설계 또한 쉽지 않다.

이유는 재설계 시스템이 기존 시스템 기능을 100% 지원해야 하면서, 재설계 도중 기존 시스템에 가한 변경도 따라잡아야 하기 때문이다. 

결과적으로 처음부터 시간을 들여 깨끗한 코드를 만드는 노력이 비용을 절감하는 방법이다.

 

태도

코드가 왜 이렇게 엉망이 되었나?

온갖 이유(변명) 들어댄다.

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

 

고객이 일정과 요구사항을 강력하게 밀어붙이는 이유는 그것이 그들의 책임이기 때문이다. 역으로 좋은 코드를 사수하는 일은 바로 우리 프로그래머들의 책임이다.

 

예를 들어, 자신이 의사라 가정하자. 어느 환자가 수술 전에 손을 씻지 말라고 요구한다.

시간이 너무걸리니까! 하지만 의사는 단호하게 거부한다. ? 질병과 감염의 위험은 환자보다 의사가 아니까. 환자 말을 그대로 따르는 행동은 범죄일 뿐만 아니라 전문가 답지 못하니까.

 

프로그래머도 마찬가지다. 나쁜 코드의 위험을 이해하지 못하는 관리자 말을 그대로 따르는 행동은 전문가답지 못하다.

 

 

 

원초적 난제

나쁜 코드는 결국 업무 속도를 늦춘다는 사실을 우리는 안다

그럼에도 불구하고 모든 프로그래머가 기한을 맞추려면 나쁜 코드를 양산할 수밖에 없다고 느낀다. 빨리 가려고 코드에 시간을 들이지 않는다.

부분이 틀렸다는 것을 명심하라

오히려 엉망진창인 상태로 인해 속도가 곧바로 늦어지고, 결국 기한을 놓친다.

빨리 가는 유일한 방법은, 언제나 코드를 최대한 깨끗하게 유지하는 습관이다.

 

 

 

깨끗한 코드라는 예술?

꺠끗한 코드를 구현하는 행위는 그림 그리기와 비슷하다.

그림을 보면 대부분 사람들이 잘그렸다 못그렸다 판단을 있지만,

그것이 그림을 잘그리는 능력이 아니다.

다시말해, 깨끗한 코드와 나쁜 코드를 구분할 안다고 깨끗한 코드를 작성할 안다는 뜻은 아니다.

 

 

깨끗한 코드란?

이 질문에 대한 대가들의 답변 요약

비야네 스트롭스트룹

나쁜 코드는 더욱 나쁜 코드가 되도록 유혹한다. 나쁜 코드를 개선하려다 나쁜 코드를 양산할 있다.

깨끗한 코드는 한가지에 집중한다.

 

그래디 부치

깨끗한 코드는 짤 쓴 문장처럼 읽혀야 한다.

 

큰 데이브 토마스

깨끗한 코드란 다른 사람이 고치기 쉬워야 한다.

읽기 쉬운 코드와 고치기 쉬운 코드는 엄연히 다르다.

테스트 케이스가 없는 코드는 깨끗한 코드가 아니다.

 

마이클 페더스

깨끗한 코드는 주의 깊게 작성한 코드다.

 

 

론 제프리스

중요도 순 나열

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

 

워드 커닝햄

읽으면서 짐작한 대로 돌아가는 코드가 깨끗한 코드다.

 

 

 

 

우리들의 생각

깨끗한 변수 이름, 깨끗한 함수, 깨끗한 클래스를 만드는 방법을 소개한다.

이책은 나와 동료들이 속한 오브젝트 멘토 진영이 생각하는 깨끗한 코드를 설명한다.

여기서 가르치는 교훈과 기법외에 다른 집단이 가르치는 것이 틀렸다는 것이 아니다!

다만 우리 진영이 가르치는 교훈과 기법은 수십 년에 걸친 경험과 반복적인 시행착오로 습득한 것이다.

 

 

우리는 저자다.

코드를 읽는 시간 코드를 짜는 시간 비율이 10 1 훌쩍 넘는다.

코드를 짜면서 우리는 끊임없이 기존 코드를 읽는다.

다시말하면 읽기 쉬운 코드가 매우 중요하다는 것이다. 비록 읽기 쉬운 코드를 짜기 쉽지 않더라도 말이다.

주변 코드가 읽기 쉬우면 새코드를 짜기도 쉽다.

주변 코드가 읽기 어려우면 새코드를 짜기 어렵다.

 

 

결론

예술에 대한 책을 읽는다고 예술가가 된다는 보장은 없다.

책을 읽는다고 뛰어난 프로그래머가 된다는 보장은 없다. 코드감각을 확실히 얻는 다는 보당도 없다.

단지, 뛰어난 프로그래머가 생각하는 방식과 그들이 사용하는 기술과 기교와 도구를 소개할 뿐이다.

나머지는 책을 읽는 독자에게 달렸다.

 

'IT책, 강의 > 클린코드(Clean Code)' 카테고리의 다른 글

4장 주석 - 나쁜 주석  (1) 2022.10.01
4장 주석 - 좋은 주석  (0) 2022.09.28
3장 함수 - 2  (2) 2022.09.25
3장 함수 - 1  (0) 2022.07.05
2장 의미 있는 이름  (0) 2022.07.01

+ Recent posts