티스토리 뷰

3장 함수

 

의도를 분명히 표현하는 함수가 목표

* 작게 만들어라!

- 함수가 후술할 원칙들을 만족하는 선에서 최대한 작게 만드는게 좋다.

 - 블록과 들여쓰기

   if문/else문/while문에 들어가는 블록은 한줄이어야 한다. 대개 그 한줄에서 함수를 호출한다.

   이로써 해당 함수 자체가 작아지고 함수에 중첩 구조가 생길만큼 커지는 것을 방지할 수 있다.

   들여쓰기 수준은 1단 혹은 2단을 넘어서면 안 된다.

 

* 한 가지만 해라!

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

- 한가지 작업만 수행하는 함수 판별법

   지정된 함수 이름 아래에서 추상화 수준이 하나인 단계들만 수행하는지?

  ( 함수는 점점 세부적인 깊이에서 여러번의 작업을 하는 방향으로 분화됨. 여기서 세부화된 깊이가 같다면 추상화 수준이 같다고 표현.)

   의미 있는 이름으로 다른 함수를 추출할 수 있는지?

   cf. https://sosimhan-dev.tistory.com/4

 

[CleanCode] 함수의 추상화 수준이란?

 오랜만에 CleanCode를 다시 읽어보고 있는데 함수의 추상화 수준에서 책 읽기를 멈추고 3번 다시 읽었다. 아무래도 책의 추상화 수준이 높은 단계 였던 것 같다. "메서드는 한 가지만 해라!"라는

sosimhan-dev.tistory.com

 

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

- 함수 내 모든 문장의 추상화 수준이 동일해야 한다.

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

   코드를 위에서 아래로 마치 책읽듯 읽을 수 있게 함수들의 추상화 수준이 한단계씩 낮아지도록 작성한다.

   현재 함수의 추상화 수준에 대한 설명과 다음으로 이어지는 아래 단계 추상화 수준도 참고해야함.

 

* Switch 문

- 너무 길기도하고 본질적으로 분기가 여러개 생기면서 n가지의 작업을 처리하는 애임.

- 사용해야한다면 잘 숨겨서 사용하자. 

 

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

- 함수가 하는 작업을 잘 표현해주는 서술적인 이름. 길어도 괜찮.

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

 

* 함수 인수

- 인수는 적을수록 좋음.

- 인수는 개념을 이해하기 어렵게 만듬.

- 인수가 많을수록 추상화 수준이 섞이기 쉬움.

- 테스트를 어렵게 만듬.

- 많이 쓰는 단항 형식

   1. 인수에 질문을 던지는 경우 ex) boolean fileExists("MyFile")  

   2. 인수를 뭔가로 변환해 결과를 반환하는 경우 ex) InputStream fileOpen("MyFile")  <String형의 파일 이름을 InputStream으로 변환하는 함수>

   3. 이벤트 함수 : 특정 이벤트가 발생했을 때 함수를 실행하는 함수 ex) passwordAttemptFailedNtimes(int attempts)

   일관성을 위해 각 경우마다 위에서 벗어나는 함수 형식은 사용하지 않는게 좋다.

   예컨데 2번 경우에서, 반환하는 값이 입력됐던 인수를 그대로 돌려주는 함수일지라도 일단 변환 함수 형식을 따르는게 좋다.

- 플래그 인수

   플래그 인수로 부울 값을 넘긴다는건 True일때와 False일때 다른 작업을 한단 뜻인데 이건 함수가 한번에 여러개의 작업을 한단 뜻임.

   즉, 플래그 인수는 구림. 쓰지마.

- 이항 함수

   인수가 많아진 만큼 함수가 더 이해하기 어려워짐. 인수 줄일 수 있다면 줄이기.

   두 개의 인수 사이에 관계가 존재하는 경우엔 그나마 허용 가능하다.

   1. 두 인수가 한개의 값을 가리키는 경우.

   2. 두 인수 사이에 자연적인 순서가 존재하는 경우

   이런 경우들... 예를 들자면 좌표값을 나타내는 Point p = new Point(0,0) 과 같은 함수는 인수 사이에 자연적인 순서가 존재하여 기억하기 쉽고 또 두개의 값이 좌표상 점 이라는 하나의 값을 표현함.

- 삼항 함수

   삼항으로 표현했을 때 그 가치가 충분하다면(가장 잘 표현된다면) 사용 못할 건 없음. 신중히 고려.

- 인수 객체

  인수가 2~3개 필요하다면 일부를 독자적인 클래스 변수로 선언하는 것을 고려해볼 수 있음.

   ex)

   Circle makeCircle(double x, double y, double radius);

   Circle makeCircle(Point center, double radius);

- 인수 List

   인수 개수가 가변적인 함수가 필요한 경우. 가변 인수 전부를 동등하게 취급하면 List형 인수 하나로 취급할 수 있음.

- 동사와 키워드

   좋은 함수 이름이란 함수의 의도나 인수의 순서와 의도를 표현해주는 애임. ex) writeField(name) : write에서 함수 의도를 Field에서 인수의 의도를 알 수 있다.

   함수 이름에 인수 이름을 넣어서 인수 순서를 표현하기도 함.

 

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

- 부수 효과는 허울만 좋은 거짓말임. 함수에선 한가지만 하기로 했잖아.

- 의도치 않은 작업을 수행하게 될 수 있음. temporal coupling 이나 order dependency 문제를 야기.

   p.55 코드 참고. 

- 출력 인수

    출력 인수란 인수로 제공한 값에 출력값을 받아오는 것을 말함. 인수가 어떨때는 input에 사용되고 어떨때는 output에 사용된다면 일관성을 해치게 됨. 

   객체 지향 프로그래밍에선 report.appendFooter()와 같이 표현이 가능하므로 굳이 출력 인수를 사용할 필요가 없음.

   즉, 함수가 속한 객체 상태를 변경하는 방식을 택하는게 좋다.

 

* 명령과 조회를 구분하라!

- 흔히 나오는 함수 형태 중 조회하여 그 조회값을 바탕으로 명령을 하는 형식이 있음. 이런 형태는 혼돈을 야기함.

- ex)

   public boolean set(String attribute, String value);

   각각 명령(동사), 조회 나타냄. 

   if (attributeExists("username")){

     setAttribute("username", "unclebob");

     ... } 

   아래와 같이 명령과 조회를 분리해 혼란을 애초에 뿌리 뽑아야함.

 

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

- if/else 문을 사용한 오류 처리 코드는 if문이 여러 단계로 중첩되는 경우가 생김.

- try/catch 문과 같은 예외 코드는 그럴 일 없음. + 이 try/catch 블록도 별도 함수로 뽑아내는 편이 좋음.

- 오류 처리도 한가지 작업임. 즉, 오류 처리 코드는 오류 처리만 수행해야 마땅함.

 

* 반복하지 마라!

- 같은 알고리즘은 한가지 함수로 처리돼야함. 쓸데없이 알고리즘을 중복해선 안된다.

 

* 구조적 프로그래밍

- 구조적 프로그래밍 원칙에선 함수는 return 문이 하나여야 한다고 하지만 그건 함수가 아주 클때만 이익이됨. 우리는 함수를 작게작게 만드는 방향으로 원칙을 세웠고 그걸 근본으로 설계 기법을 배우는 중이므로 크게 이득이 되지 못함.

- 즉, 함수를 작게 만든다면 간혹 return, break, continue를 여러차례 사용해도 괜찮음.

 

 *  함수를 어떻게 짜죠?

- 글짓기와 비슷하다. 처음엔 일단 코드를 짜는거임. 그 후에 코드를 다듬는 과정을 거쳐서 규칙을 만족하는 코드를 완성하는 것.

   

 

 

      

 

 

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

클린 코드) 5장 핵심 정리  (0) 2022.01.28
클린 코드) 4장 핵심 정리  (0) 2022.01.22
클린 코드) 2장 핵심 정리  (0) 2022.01.14
클린 코드) 1장 핵심 정리  (0) 2022.01.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함