[클린코드 완독스터디] TIL (2022.02.21)

yourjin·2022년 2월 27일
0

read.log

목록 보기
31/37
post-thumbnail

TIL (2022.02.21)

DAY 8

🔖 오늘 읽은 범위 : 14장, 점진적인 개선


😃 책에서 기억하고 싶은 내용을 써보세요.

  • Args: 1차 초안
    • 내가 맨 처음 짰던 Args 클래스다. 코드는 ‘돌아가지만’ 엉망이다.
    • 인스턴스 변수 개수만도 압도적이다. 'TILT' 와 같은 희한한 문자열, HashSets, TressSets, try-catch-catch 블록 등 모두가 지저분한 코드에 기여하는 요인이다.
    • 처음부터 지저분한 코드를 짜려는 생각은 없었다. (...) 하지만 어느 순간 프로그램은 내 손을 벗어났다. 코드는 조금씩 엉망이 되어갔다.
    • 그래서 멈췄다
      • 계속 밀어붙이면 프로그램은 어떻게든 완성하겠지만 그랬다가는 너무 커서 손대기 어려운 골칫거리가 생겨날 참이었다.
      • 그래서 나는 기능을 더 이상 추가하지 않기로 결정하고 리펙터링을 시작했다.
        1. 인수 유형에 해당하는 HashMap을 선택하기 위해 스키마 요소의 구문을 분석한다.
        2. 명령행 인수에서 인수 유형을 분석해 진짜 유형으로 변환한다.
        3. getXXX 메서드를 구현해 호출자에게 진짜 유형을 반환한다.
      • 인수 유형은 다양하지만 모두가 유사한 메서드를 제공하므로 클래스 하나가 적합하다 판단했다. 그래서 ArgumentMarshaler라는 개념이 탄생했다.
    • 점진적으로 개선하다
      • 프로그램을 망치는 가장 좋은 방법 중 하나는 개선이라는 이름 아래 구조를 크게 뒤집는 행위다.
      • 그래서 나는 테스트 주도 개발(Test-Driven Development, TDD)이라는 기법을 사용했다. TDD는 언제 어느 때라도 시스템이 돌아가야 한다는 원칙을 따른다. 다시 말해, TDD는 시스템을 망가뜨리는 변경을 허용하지 않는다. 변경을 가한 후에도 변경 전과 똑같이 돌아가야 한다는 말이다.
      • 변경 전후에 시스템이 똑같이 돌아간다는 사실을 확인하려면 언제든 실행이 가능한 자동화된 테스트 슈트가 필요하다.
      • 두 테스트 모두 언제든 실행이 가능했으며, 시스템이 두 테스트를 통과하면 올바로 동작한다고 봐도 좋았다. 그래서 나는 시스템에 자잘한 변경을 가하기 시작했다. 코드르 변경할 때마다 시스템은 변경 전과 다름없이 돌아갔다.
      • 앞서 새 인수 유형을 추가하려면 세 곳(parse, get, set)을 변경해야 한다고 말했는데, 위에서 수정한 부분과 정확히 일치한다는 사실에 주목한다. 불행히도 사소한 변경이었으나 몇몇 테스트 케이스가 실패하기 시작했다. → 다음 변경으로 넘어가기 전에 나는 재빨리 이것부터 고쳐야 했다.
  • String 인수
    • String 인수를 추가하는 과정은 boolean 인수와 매우 유사했다. HashMap을 변경한 후 parse, set, get 함수를 고쳤다.
    • 단, 내가 모든 논리를 (파생 클래스를 만드는 대신) ArgumentMarshaler 클래스에 곧바로 넣었다는 사실을 의아하게 여길지도 모르겠다.
    • 이번에도 앞서 구현과 마찬가지로 한 번에 하나씩 고치면서 테스트를 계속 돌렸다. 테스트 케이스가 하나라도 실패하면 다음 변경으로 넘어가기 전에 오류를 수정했다.
    • 지금쯤이면 내 의도를 눈치챘으리라. 일단 각 인수 유형을 처리하는 코드를 모두 ArgumentMarshaler 클래스에 넣고 나서 ArgumentMarshaler 파생 클래스를 만들어 코드를 분리할 작정이었다. 그러면 프로그램 구조를 조금씩 변경하는 동안에도 시스템의 정상 동작을 유지하기 쉬워지기 때문이다.

      ArgumentMarshaler
      → BooleanArgumentMarshaler
      → IntegerArgumentMarshaler
      → StringArgumentMarshaler

    • 다음으로 나는 알고리즘 처음에 나오는 (인수 유형마다 따로 만든) 맵 세 개를 없앴다. 그러면 전체 시스템이 훨씬 일반적으로 변한다.

🤔 오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

  • 오늘 가장 인상 깊었던 부분은 TDD에 관한 내용이었다. TDD가 처음 언급된 것은 아니지만, 이번 장에서 보여준 예시가 TDD의 장점을 잘 보여주었다고 생각한다. 처음부터 명확하게 요구사항을 구현할 수 있다면, 테스트는 사실 무의미하다. 하지만 실제 시스템은 굉장히 많은 가변적인 요소들로 구성되어있다. 그리고 내가 짠 코드가 ‘깨끗한’ 코드인지도 확신할 수 없다. 지금은 깨끗해보여도 이후의 변경으로 인해 더러워질 수도 있기 때문이다. 이런 점 때문에 우리는 앞으로도 계속 우리의 코드가 제대로 기능하고 있다는 ‘검증’ 즉, TDD가 필요하다고 느꼈다.

🔎 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

  • 없음

소감 3줄 요약

  • 어느 순간부터 코드가 조금씩 엉망이 되고 내 손을 떠났다는 느낌을 받으면, 기능을 더 이상 추가하지 말고 리펙터링 하자.
  • TDD는 시스템을 망가뜨리는 변경을 허용하지 않는다. 따라서 TDD를 이용한 지속적인 테스트를 통해 점진적인 개선이 가능하다.
  • 일단 클래스에 몰아넣고 이후 파생 클래스를 만들면, 프로그램 구조를 변경하는 동안에도 시스템의 정상 동작을 유지하기 쉬워진다.
profile
make it mine, make it yours

0개의 댓글