CS공부(개념)/독후감

클린코드 6주차: SerialDate 리팩터링, 냄새와 휴리스틱

cantor 2023. 9. 12. 15:10

230912 클린코드 6주 차

클린코드 북스터디를 하며 작성한 독후감 겸 요약글입니다.

로버트 c 마틴- 클린코드

 

이번주에는 16장 Serial Date 리팩터링, 그리고 17장 냄새와 휴리스틱을 읽었습니다.

 

16장에서는 JUnit에 이어 또 다른 라이브러리 코드를 분석 및 개선하고,

17장은 지금까지 책에서 다룬 기법을 총정리합니다.

 

이제 책의 거의 마지막 부분을 달려가고 있네요.

최근에 리액트 스터디를 시작해서, 책에서 읽은 기법들을 하나하나 검토하고 

개선하여 적용해 볼 생각에 힘이 납니다.

 

 

16장 Serial Date 리팩터링

JUnit 들여다보기에 이어서 또 다른 클래스를 리팩터링 하는 쳅터입니다.

 

리팩터링 대상:
David Gilbert - SerialDate Class
https://www.jfree.org/jcommon/api/org/jfree/date/SerialDate.html

 

저자는 실제 리팩터링 작업에 대한 이야기에 앞서 코드의 원작자인 David Gilbert에게 경의를 표합니다.

 

코드의 검토 및 개선은 저작자에 대한 악의를 품고 비난하려는 것이 아니라,
전문가로서 동료의 작업물에 대한 면밀한 검토를 수행하는 과정임을 명확히 밝힙니다.

 

아무래도 리팩터링이라는 것이 작업물의 문제점을 지적하고,
개선안을 제시하는 것이기 때문에 때로는 예의에 어긋나는 것처럼 보일 수도 있어서 그런가 봅니다.

 

저도 누군가의 코드를 리뷰 할 때에 먼저 Respect를 보여주어야겠습니다.

 

17장 냄새와 휴리스틱

 

 

이 장에서 클린 코드의 저자는 리팩터링에서 소개하는 코드에서 나는 "냄새"에 대한

자신의 생각과 개선 방식에 대해 이야기합니다

 

리팩터링은 마틴 파울러라는 개발자가 작성한 클린코드 패턴에 대한 책입니다.

최근에 자바스크립트 버전으로 2판이 출간되었지요.

 

여기서 말하는  "냄새"는 일종의 정립된 안티패턴으로, 코드를 개선해야 할 이유입니다.

오류, 유지보수가 어려운 구조등 다양한 이유를 함축적으로 표현하죠.

 

리팩터링의 집필기간 중에 저자는 갓난아기를 키우고 있었다고 합니다.

아이가 대변을 누면, 시끄럽게 울지 않아도 냄새를 통해 이를 파악하고 기저귀를 갈아주어야 했습니다.

 코드 냄새라는 용어는 여기서 착안했다고 합니다.

 

직접적인 문제(소리)가 발생하기 전에 개발자들이 알아서 파악하길 바라는 마음이 담겨있지요.

 

보통은  클린코드를 작성하는 행위를 미학적 프로그래밍 (aesthetics programming)
이라고 표현한다고 합니다. 수정이 필요한 코드는 "프로그래밍 미학에 어긋나는 코드" 이죠.

 

하지만 리팩터링의 저자는 "이 코드에서는 냄새가 난다"와 같은 표현으로
개선이 필요함을 객관적이고 쉬운 표현으로  전달하고 싶었다고 합니다.

 

다시 클린코드로 돌아가겠습니다.

 

리팩터링에서 빌려온 것은 냄새의 목록일 뿐입니다.

 

본문에서는 주석, 환경, 함수, 자바, 이름, 테스트를 주제로
책의 앞부분에서 이야기했던 클린-코드 기법들을 한 번씩 다시 소개합니다.

 

코드 냄새 목록

 

주석 Comment

  1. 부적절한 정보
  2. 쓸모없는 주석
  3. 중복된 주석
  4. 성의 없는 주석
  5. 주석 처리된 코드

환경 Enviorment

  1. 여러 단계로 나눠진 빌드
  2. 여러 단계로 나눠진 테스트

함수 Function

  1. 너무 많은 인수
  2. 출력인수
  3. 플래그 인수
  4. 죽은 함수

일반 General

  1. 한 소스 파일에 여러 언어
  2. 당연한 동작
  3. 잘못 처리된 경계
  4. 안전 절차 무시
  5. 중복
  6. 올바르지 못한 추상화 수준
  7. 파생 클래스에 의존하는 기존클래스
  8. 과도한 정보
  9. 죽은 코드
  10. 수직 분리
  11. 일관성 부족
  12. 잡동사니
  13. 인위적 결합
  14. 기능 욕심
  15. 선택자 인수
  16. 모호한 의도
  17. 잘못 지운 책임
  18. 부적절한 static 함수
  19. 서술적 변수
  20. 이름과 기능 다른 함수
  21. 알고리즘을 이해하라
  22. 논리적 의존성은 물리적으로 드러내라
  23. if/else 혹은 switch/case 보다는 다형성을 사용하라
  24. 표준 표기법을 따르라
  25. 매직 숫자는 명명된 상수로 교체하라
  26. 정확하라
  27. 관례보다 구조를 사용하라
  28. 조건을 캡슐화하라
  29. 부정 조건은 피하라
  30. 함수는 한 가지만 해야 한다
  31. 숨겨진 시간적인 결합
  32. 일관성을 유지하라
  33. 경계 조건을 캡슐화하라
  34. 함수는 추상화 수준을 한 단계만 내려가야 한다
  35. 설정 정보는 최상위 단계에 둬라
  36. 추이적 탐색을 피하라

자바 Java

  1. 긴 import 목록을 피하고 와일드카드를 사용하라
  2. 상수는 상속하지 않는다
  3. 상수 대 Enum

이름 Name

  1. 서술적인 이름을 사용하라
  2. 적절한 추상화 수준에서 이름을 선택하라
  3. 가능하다면 표준 명명법을 사용하라
  4. 명확한 이름
  5. 긴 범위는 긴 이름을 사용하라
  6. 인코딩을 피하라
  7. 이름으로 부수 효과를 설명하라

테스트 Test

  1. 불충분한 테스트
  2. 커버리지 도구를 사용하라
  3. 사소한 테스트를 건너뛰지 마라
  4. 무시한 테스트는 모호함을 뜻한다
  5. 경계 조건을 테스트하라
  6. 버그 주변은 철저히 테스트하라
  7. 실패 패턴을 살펴라
  8. 테스트 커버리지 패턴을 살펴라
  9. 테스트는 빨라야 한다

함께 나눠볼 만한 얘기

  1. 소프트 스킬을 향상하기 위한 여러분들의 방법이나 노력이 있나요?

serialDate의 저작자에게 존중을 먼저 보여주는 저자의 태도나,
리팩터링의 저자가 "냄새"라는 용어를 만드는 과정을 관찰하면서 

클린 코드 기술보다는 소프트 기술에 더 관심이 갔습니다.

 

개발이라는 것이 협업이 중요한 만큼 사용하는 용어 선택이나
말투가 중요한 것 같습니다. 여러분들은 소프트 스킬을 키우기 위해 어떤 노력을 하나요?

  1. 여러분이 평소에 정립해 놓았거나, 최근에 느낀 냄새는 무엇이 있나요?

저는 이번에 트위터 클론코딩 프로젝트를 하면서 "너무많은 import "라는냄새를 느꼈습니다.

 

routes라는 폴더에는 페이지 하나를 담당하는 component 파일들이 들어있습니다.

그리고 모든 파일은 Router.tsx라는 단 하나의 파일에서만 사용합니다.

처음에는 각 컴포넌트를 사용할 때마다 import 문을 하나씩 추가하는 방식을 사용했었는데,
이렇게 하다 보니 파일 상단이 import 문으로 뒤덮여서 코드가 너무 길어졌습니다.

 

그래서 routes 폴더내부의 모든 컴포넌트를 하나의 모듈로 모아 export 해주었습니다.

import * as Routes from "@/routes";
const {CreateAccount, Home, Login, Profile} = Routes;

 

여러분도 이렇게 최근에 느낀 코드에대한 냄새나, 정립해놓은 안티패턴이 있나요?

 

  1. 패턴과 안티패턴이 뒤바뀌어도 결코 변하지 않는 클린코드 기법은 무엇일까요?
    또는 어떤 마음방향으로 클린 소프트웨어를 공부해야 변화에 유연하게 대처할 수 있을까요?

바닐라 JS를 공부할 때에는 인라인 이벤트 핸들링 방식을 피하라는 권고가 많이 있었습니다.
그러나 리액트로 넘어오면서 인라인 이벤트 핸들링이 흔히 사용되는 방법 중 하나가 되었습니다.

또, 책을 읽는 내내 클린 코드의 저자의 switch에 대한 반감을 계속해서 확인 할 수 있었습니다.
그런데 이것은 실제로 switch가 문제를 가지고있는것은 아니라고합니다.

 

책이 집필되던 시기에는 다형성이 상식으로 통용되지않았다고합니다.
그래서 각각의 개별 클래스로 분리해야 할 로직을 switch 문 내부의
case에 모두 때려 박은 코드들이 많았다고 합니다.

그래서 그당시 switch 문은 언제나 검토 대상 코드 1순위였지만, 지금은 그렇지 않다고합니다.

이처럼 패턴과 안티패턴이 변하는 상황에서도 유용한 기법은 어떤 것이 있을까요?

또는 어떤 마음가짐으로 소프트웨어 공학을 받아들여야할까요?

저는 Dry 원칙같이 구체적인 코드패턴에서 벗어난 원칙을 중요시 여기고
디테일한 부분은 전부 유연하게 언제든 버릴수 있지 않을까 하는 생각이 들었습니다.