티스토리 뷰
반응형
[클린코드 - http://www.yes24.com/Product/Goods/11681152]
- 어떤 프로그램이든 가장 기본적인 단위가 함수
작게 만들어라!
- 함수를 만드는 첫째 규칙은 '작게!'. 둘째 규칙은 '더 작게!'이다
- 켄트 벡의 Sparkle
- 모든 함수가 2줄, 3줄, 4줄 정도였음
- 각 함수가 너무도 명백하고, 각 함수는 이야기 하나를 표현했고, 각 함수가 너무도 멋지게 다음 무대를 준비했음
=> 이것이 답이다!
- 블록과 들여쓰기
- if 문/else 문/while 문 등에 들어가는 블록은 한 줄이어야 한다
- 그러면 바깥을 감싸는 함수(enclosing function)이 작아질뿐만 아니라 코드를 이해하기 쉬워진다
- 중첩 구조가 생길만큼 함수가 커져서는 안 된다!
한 가지만 해라!
함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다. |
- 함수를 만드는 이유는 큰 개념을 (함수 이름을) 다음 추상화 수준에서 여러 단계로 나눠 수행하기 위해서이다
- 함수는 간단한 TO 문단으로 기술할 수 있다
- 의미 있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈이다
함수 당 추상화 수준은 하나로!
- 함수가 확실히 '한 가지' 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 한다
- 한 함수 내에 추상화 수준을 섞으면 코드를 읽는 사람이 헷갈린다
- 근본 개념과 세부사항을 구분하기 어렵고 이 것들이 뒤섞이기 시작하면 사람들이 함수에 세부사항을 점점 더 추가하게 된다
- 위에서 아래로 코드 읽기: 내려가기 규칙
- 코드는 위에서 아래로 이야기처럼 읽혀야 좋다
- 위에서 아래로 프로그램을 읽으면 함수 추상화 수준이 한 번에 한 단계씩 낮아진다
- 핵심은 짧으면서도 '한 가지'만 하는 함수다
Switch 문
- switch 문은 작게 만들기 어렵다
- 본질적으로 switch 문은 N가지를 처리한다
- 다형성(polymorphism)을 이용해 switch 문을 저차원 클래스에 숨기고 반복하지 말자
- 상속 관계로 숨기고 다른 코드에 노출하지 않는다
서술적인 이름을 사용하라!
- 길고 서술적인 이름이 짧고 어려운 이름보다 좋다
- 길고 서술적인 이름이 길고 서술적인 주석보다 좋다
- 함수 이름을 정할 때는 여러 단어가 쉽게 읽히는 명명법을 사용하고 여러 단어를 사용해 함수 기능을 잘 표현하는 이름을 선택한다
- 함수가 작고 단순할수록 서술적인 이름을 고르기 쉬워진다
- 서술적인 이름을 사용하면 개발자 머릿속에서도 설계가 뚜렷해지므로 코드를 개선하기 쉬워진다
함수 인수
- 함수에서 이상적인 인수 개수는 0개(무항)다
- 3개(삼항)은 가능한 피하는 편이 좋다
- 4개 이상(다항)은 특별한 이유가 있어도 사용하면 안된다
- 인수는 개념을 이해하기 어렵게 만든다
- 테스트 관점에서도 인수는 함수를 검증할 때 많은 조합을 생각해야해서 어렵다
- 출력 인수는 입력 인수보다 이해하기 어렵다
- 최선은 입력 인수가 없는 경우이며, 차선은 입력 인수가 1개뿐인 경우다
- 많이 쓰는 단항 형식
- 인수에 질문을 던지는 경우 ex) boolean fileExists("MyFile")
- 인수를 뭔가로 변환해 결과를 반환하는 경우 ex) InputStream fileOpen("MyFile")
- 이벤트 : 입력 인수만 있고 출력 인수는 없음
- 프로그램은 입력 인수로 시스템 상태를 바꿈
- 이벤트라는 사실이 코드에 명확히 드러나야 함
- ex) passwordAttemptFailedNtimes(int attempts)
- 플래그 인수
- 플래그 인수는 추하고 끔찍하다
- 대놓고 한꺼번에 여러 일을 처리한다는 뜻이기 때문
- 이항 함수
- 순서, 주춤, 무시로 야기되는 문제가 있다
- 인자가 2개인 함수는 인수가 1개인 함수보다 이해하기 어렵다
- 적절한 경우 : 2개가 한 값을 표현하는 두 요소이고 자연적인 순서가 있을 때
- 이항함수는 위험이 따르고 가능하면 단항 함수로 바꾸도록 애써야 한다
- 삼항 함수
- 인수가 3개인 함수는 인수가 2개인 함수보다 훨씬 더 이해하기 어렵다
- 순서, 주춤, 무시로 야기되는 문제가 두 배 이상 늘어난다
- 삼항 함수를 만들 때는 신중히 고려해야 한다
- 인수 객체
- 인수가 2-3개 필요하다면 일부를 독자적인 클래스 변수로 선언할 가능성을 짚어본다
- 눈속임이라 생각할 수 있지만 변수를 묶어 넘기려면 이름을 붙여야 하므로 결국은 개념을 표현하게 된다
- 인수 목록
- 인수 개수가 가변적인 함수는 가변 인수 전부를 동등하게 취급하면 List형 인ㄴ수 하나로 취급할 수 있기 때문에 사실상 이항 함수다
- 가변 인수를 취하는 함수는 단항, 이항, 삼항 함수로 취급할 수 있다
- 동사와 키워드
- 함수의 의도나 인수의 순서와 의도를 제대로 표현하려면 좋은 함수 이름이 필수다
- 단항 함수는 함수와 인수가 동사/명사 쌍을 이뤄야 한다
- 함수 이름에 인수 이름을 넣으면 인수 순서를 기억할 필요가 없어진다
부수 효과를 일으키지 마라!
- 부수 효과는 예상치 못하게 클래스 변수를 수정하거나 함수로 넘어온 인수나 시스템 전역 변수를 수정한다
- 시간적인 결합(temporal coupling)이나 순서 종속성(order dependency)을 초래한다
- 출력 인수 : 입력의 상태를 변경하는 인수
- 일반적으로 출력 인수는 피해야 한다
- 함수에서 상태를 변경해야 한다면 함수가 속한 객체 상태를 변경하는 방식을 택하라
명령과 조회를 분리하라!
- 함수는 뭔가를 수행하거나 뭔가에 답하거나 둘 중 하나만 해야 한다
- 객체 상태를 변경하거나 객체 정보를 반환하거나 둘 중 하나이다
- 명령과 조회를 분리해 혼란을 뿌리뽑아야 한다
오류 코드보다 예외를 사용하라!
- 명령 함수에서 오류 코드를 반환하는 방식은 명령/조회 분리 규칙을 미묘하게 위반한다
- if 문에서 명령을 표현식으로 사용하기 쉬운 탓
- 오류 코드 대신 예외를 사용하면 오류 처리 코드가 원래 코드에서 분리되므로 코드가 깔끔해진다
- Try / Catch 블록 뽑아내기
- try/catch 블록은 코드 구조에 혼란을 일으키며 정상 동작과 오류 처리 동작을 뒤섞으므로 별도 함수로 뽑아내는 편이 좋다
- 오류 처리도 한 가지 작업이다
- 오류를 처리하는 함수는 오류만 처리해야 마땅하다
- 함수에 키워드 try가 있다면 함수는 try 문으로 시작해 catch/finally 문으로 끝나야 한다
- Error.java 의존성 자석
- Error enum은 다른 클래스에서 import해서 사용해야 하므로 Error enum이 변하면 Error enum을 사용하는 클래스 전부를 다시 컴파일하고 배치해야 한다
- 오류 코드 대신 예외를 사용하면 재컴파일/재배치 없이도 새 예외 클래스를 추가할 수 있다
- OCP(Open Closed Principle)을 보여주는 예
반복하지 마라!
- 중복은 문제다
- 코드 길이가 늘어나고 알고리즘이 변하면 수정할 곳이 많고 하나라도 빠뜨리면 오류가 발생할 확류롣 훨 높아진다
- 중복은 소프트웨어에서 모든 악의 근원이다
구조적 프로그래밍
- Dijkstra : 모든 함수와 함수 내 모든 블록에 입구(entry)와 출구(exit)가 하나만 존재해야 한다
- 함수는 return문이 하나여야 한다
- 루프 안에서 break이나 continue를 사용해서는 안되며 goto는 절대로 안된다
- => 그러나 함수가 아주 클 때만 이익을 제공
- 함수를 작게 만든다면 간혹 return, break, continue를 여러 차례 사용해도 괜찮다
- 단일 입/출구 규칙(sing entry-exit rule)보다 의도를 표현하기 쉬워짐
- goto문은 큰 함수에서만 의미가 있으므로 작은 함수에서는 피해야 함
함수를 어떻게 짜죠?
- 처음에는 길고 복잡한 서투른 코드를 빠짐없이 테스트하는 단위 테스트 케이스를 만듦
- 그 후에 코드를 다듬는다(코드는 항상 단위 테스트를 통과)
결론
- 모든 시스템은 특정 응용 분야 시스템을 기술할 목적으로 프로그래머가 설계한 도메인 특화 언어(Domain Specific Language, DSL)로 만들어 진다
- 함수는 그 언어에서 동사며, 클래스는 명사다
- 프로그래밍 언어라는 수단을 사용해 좀 더 풍부하고 좀 더 표현력이 강한 언어를 만들며 이야기(시스템)을 풀어간다
- 시스템에서 발생하는 모든 동작을 설명하는 함수 계층이 언어에 속한다
- 진짜 목표는 시스템이라는 이야기를 풀어가는 데 있다
반응형
'study > 클린코드' 카테고리의 다른 글
6. 객체와 자료 구조 (0) | 2021.06.06 |
---|---|
5. 형식 맞추기 (0) | 2021.06.06 |
4. 주석 (0) | 2021.06.02 |
2. 의미 있는 이름 (0) | 2021.05.26 |
1. 깨끗한 코드 (0) | 2021.05.24 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- docker for mac
- Kubernetes
- linuxkit
- QuickTimePlayer
- JavaScript
- ddd
- 클린코드
- IntelliJ
- gasmask
- java
- docker pull limit
- kotlin In Action
- 스프링부트
- 스프링
- 쿠버네티스
- 자바스크립트
- cacheable
- springboot
- 자바
- gradle
- Spring
- kotlin
- back merge
- k8s
- 코틀린
- 도메인주도설계
- docker
- 도커
- clean code
- ImagePullBackOff
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함