책의 제목 그대로 깨끗한 코드 작성법을 알기 위해 읽게 되었다.
이 책에서 워드 커닝햄(Ward Cunningham)의 말을 인용한 부분이 인상깊었다.
코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면,
깨끗한 코드라 불러도 되겠다.
코드가 그 문제를 풀기 위한 언어처럼 보인다면,
아름다운 코드라 불러도 되겠다.
깨끗한 코드는 읽으면서 놀랄 필요가 없어야 한다고 워드는 말한다.
즉, 코드를 독해하느라 머리를 쥐어짤 필요가 없어야 한다고 말한다.
프로그래밍 공부를 시작한지 별로 안되었지만, 이 인용문을 보면서 저절로 고개를 끄덕이게 되었다.
반드시 알아야 하는 객체 지향 설계의 다섯 가지 원칙은 다음과 같다.
- SRP(The Single Responsibilty Principle) : 클래스에는 한 가지, 단 한 가지 변경 이유만 존재해야 한다.
- OCP(The Open Closed Principle) : 클래스는 확장에 열려 있어야 하며 변경에 닫혀 있어야 한다.
- LSP(The Liskov Substitution Principle) : 상속받은 클래스는 기초 클래스를 대체할 수 있어야 한다.
- DIP(The Dependency Inversion Principle) : 추상화에 의존해야 하며, 구체화에 의존하면 안 된다.
- ISP(The Interface Segregation Principle) : 클라이언트에 밀접하게 작게 쪼개진 인터페이스를 유지한다.
프로젝트를 생성할 때, 짓는 모든 이름들은 의미가 있어야 한다고 저자는 말한다.
요즘 코드를 작성하면서, 짓게 되는 모든 이름들을 신중히 지으려고 노력하고 있다.
책에서는 짧은 이름이 좋다고 말하지만, 의도가 분명하고 의미가 있는 이름도 중요하다고 말하기에,
이름이 꽤나 길어지더라도, 확실한 의도를 갖는 명명을 하려 노력한다.
이 책에서, 물음표를 떠올리게 만들었던 구절은 '발음하기 쉽게', '검색하기 쉬운' 이름들을 사용하라는 거였다.
그 후 내용들을 읽으면서, 저절로 이해하게 되었다.
발음하기 쉽게 명명하란 말은, 추후에 실무에서 일하게 된다면,
팀 동료들과 함께한 프로젝트에서의 이름들을 무수히 많이 입 밖으로 내뱉을 것이기 때문이란 이유이다.
또, 검색하기 쉽게하란 말은 무수히 긴 코드 속에서 특정 이름을 찾을 때,
7을 입력해서 찾을 경우, 7을 포함한 모든 이름들(서로 관련이 없는)을 찾게 될 것이기 때문이란 이유이다.
정말 기발하고 신기했던 명명법들을 보고 나니, 코드를 짤 때 더 신중해야겠다는 생각이 든다.
다음은 함수에 대한 내용들이다.
변수가 속성이라면, 함수는 기능의 역할을 한다.
제일 중요하게 생각했던 부분은 '하나의 함수는 하나의 기능을 구현하는 게 좋다'이다.
어찌보면 당연한 소리겠지만, 정신없이 코드를 써내려 가다 보면 한 함수에서 여러 기능을 구현하도록 짤 때가 종종 있다.
책의 이름처럼 클린하게 코드를 작성하려면, 앞서 언급했던 함수 작성법을 따르는 게 좋을 것 같다는 생각이다.
주석에 관해서도 언급을 하고 있다.
주석은 주석일 뿐, 안 쓰는 게 좋다고 말하는 것 같다. (내가 의도를 잘 파악하고 있는진 잘 모르겠지만..)
코드로 그 주석을 대신하는 게 훨씬 좋다고 말한다.
다만, 코드 뿐으로 코드를 읽는 사람이 이해를 못할 경우에만, 어쩔 수 없이 적어주어야 한다.
알고리즘 학습을 하면서, 수도 코드에 대한 학습을 했었다.
'수도 코드는 세세하게 작성하면 좋다'라고 배웠고, 난 그걸 최대한 길게 쓰면 좋다고 이해했다.
이 책의 주석 파트를 읽을 때, 전에 알고 있던 지식(알고리즘 수도 코드관련)들과 상반되는 거 아닌가?라는 의문이 들었다.
그럼, 알고리즘 풀이를 할 때, 수도 코드를 안써야 하나...?
내가 내린 결론은 '알고리즘을 풀기 위해서 수도 코드는 필요하지만, 풀고 난 후에는 필요 없다'였다.
이제 알고리즘을 풀 때면, 수도 코드를 세세하게 작성해서 풀이를 하고, 풀이가 끝나면 설명이 필요한 부분만 빼고 모두 지우려 한다. (설명 주석을 지울 수 있는 건 위의 명명법으로 어느 정도 대체 가능하다고 생각한다.)
주석 또한 클린하게 코드를 짜기 위해선 신중하게 고려해야 하는 사항이라는 생각을 하게 되었다.
저자는 코드를 신문 기사처럼 작성하라고 말한다.
정말 동감이 가면서도, 쉽지는 않을 것 같다는 생각이 든다.
신문을 읽어보면 제목으로 이목을 끌고(= 코드를 읽고 싶게 만들고) 위에서 아래로 읽어 내려갈수록 세세하게 묘사한다.
코드 또한 위에서 아래로 내려갈수록 세세하게 묘사하고, 말단에는 가장 저차원의 함수와 세부 내역이 나와야한다고 말하고 있다. 이건.. 너무 맞는 말인 것 같다.
애자일 소프트웨어 개발 선언
https://agilemanifesto.org/iso/ko/manifesto.html
단위 테스트
TDD 법칙 3가지
- 실패하는 단위 테스트를 작성할 때까지는 실제 코드를 작성하지 않는다.
- 컴파일은 성공하되, 실행이 실패하는 정도로만 단위 테스트를 작성한다.
- 현재 실패하는 테스트 코드를 당장에 통과할 정도로만 실제 코드를 작성한다.
깨끗한 테스트 코드를 유지하는 것은 중요하다. 실제 코드를 관리하는 것만큼 테스트 코드를 관리해야 한다.
테스트는 유연성, 유지보수성 및 재사용성을 제공한다. 테스트 케이스가 있으면 실제 코드의 변경이 쉬워진다.
깨끗한 테스트 코드라는 것은 한 마디로 표현하자면, 가독성 뿐이다.
테스트 코드에서 가장 중요한 건 가독성!!!
- 테스트 자료를 만든다.
- 테스트 자료를 조작한다.
- 조작한 결과가 올바른지 확인한다.
도메인이 특화된 언어(DSL)은 테스트 코드에서 사용하는 특수 API가 될 수 있다.
(여기서 DSL은 별도로 구현한 함수와 유틸리티를 뜻한다)
이렇게 짜여진 테스트 코드는 읽는 독자로 하여금 눈에 더 잘 들어오게끔 만든다.
이중 표준
테스트 코드는 실제 코드만큼 효율적일 필요는 없다. 이것이 관리 차원에서 테스트 코드가 덜 중요하다고 말하는 것은 아니다. 테스트 환경에서 돌아가는 코드인만큼, 실제 환경에서는 전혀 쓰일 수 없는, 그런 코드를 짜는 것이 가능하다.
예를 들어, 메모리나 CPU 효율을 따지지 않는 코드를 테스트 환경에서는 짤 수가 있다. 이것은 코드의 깨끗함과는 철저히 무관하다.
테스트 메서드 당 개념 하나를 추구하고, assert문은 최소한으로 줄이라고 말한다.
given-when-then(TEMPLATE METHOD) 패턴을 사용해라.
F.I.R.S.T
- F(Fast) : 빠르게
테스트 코드는 빠르게 돌아야 한다.
- I(Independent) : 독립적으로
각 테스트들은 서로 의존하면 안 된다.
- R(Repeatable) : 반복가능하게
테스트는 어떤 환경에서도 반복 가능해야 한다.
책에서는 집에 가는 버스 안(네트워크가 터지지 않는)에서도 실행할 수 있어야 한다고 말한다.
- Self-Validating : 자가검증하는
성공 아니면 실패(bool)으로 결과가 나와야 한다.
- Timely : 적시에
실제 코드를 작성하기 전에 단위 테스트를 작성한다.
책은 테스트 코드는 정말 중요한 부분이라고 말한다.
실제 코드와 연관지어, 깨끗하지 못한 테스트 코드는 실제 코드를 망치게 된다라고도 말한다.
테스트 코드를 주제로 다루는 책 한 권을 별도로 사서 깊이 있게 공부해볼 필요가 있어보인다.
(책의 내용을 읽을 때마다, 인상 깊거나 중요한 부분, 나의 느낌을 지속적으로 기록하려 합니다.)
'생각 정리 > 독서' 카테고리의 다른 글
[책 리뷰] 객체지향의 사실과 오해 (7) | 2024.02.21 |
---|