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

 

3.1 기이한 이름

  • 코드를 명료하게 표현하는 데 가장 중요한 요소 하나는 바로 ‘이름'이다.
    • 그래서 함수, 모듈, 변수, 클래스 등은 그 이름만 보고도 각각이 무슨 일을 하고 어떻게 사용해야 하는지 명확히 알 수 있도록 엄청나게 신경 써서 이름을 지어야 한다.
    • 마땅한 이름이 떠오르지 않는다면 설계에 더 근본적인 문제가 숨어 있을 가능성이 높다.

3.2 중복 코드

  • 똑같은 코드 구조가 여러 곳에서 반복된다면 하나로 통합하여 더 나은 프로그램을 만들 수 있다.
    • 코드가 중복되면 각각을 볼 때마다 서로 차이점은 없는지 주의 깊게 살펴봐야 하는 부담이 생긴다.

3.3 긴 함수

  • 간접 호출의 효과, 즉 코드를 이해하고, 공유하고, 선택하기 쉬워진다는 장점은 함수를 짧게 구성할 때 나오는 것이다.
  • 짧은 함수로 구성된 코드를 이해하기 쉽게 만드는 가장 확실한 방법은 좋은 이름이다. 함수 이름을 잘 지어두면 본문 코드를 볼 이유가 사라진다.
    • 함수 이름은 동작 방식이 아닌 ‘의도(intention)’가 드러나게 짓는다.

3.5 전역 데이터

  • 전역 데이터가 조금뿐이라면 감당할 수 있겠지만, 많아지면 걷잡을 수 없게 된다.
  • 우리는 전역 데이터가 아주 조금만 있더라도 캡슐화하는 편이다. 그래야 소프트웨어가 진화하는 데 따른 변화에 대처할 수 있다.

3.7 뒤엉킨 변경

  • 코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그 부분만 수정할 수 있기를 바란다.
    • 이렇게 할 수 없다면 뒤엉킨 변경과 산탄총 수술 중 하나가 풍긴다.
  • 뒤엉킨 변경은 단일 책임 원칙(Single Responsibility Principle, SRP)이 제대로 지켜지지 않을 때 나타난다.
    • 즉, 하나의 모듈이 서로 다른 이유들로 인해 여러 가지 방식으로 변경되는 일이 많을 때 발생한다.
    • 예컨대 지원해야 할 데이터베이스가 추가될 때마다 함수 세 개를 바꿔야 하고, 금융 상품이 추가도릴 때마다 또 다른 함수 네 개를 바꿔야 하는 모듈이 있다면 뒤엉킨 변경이 발생했다는 뜻이다.

3.10 데이터 뭉치

  • 데이터 항목들은 어린아이 같은 면이 있다. 서로 어울려 노는 걸 좋아한다. 그래서 데이터 항목 서너 개가 여러 곳에서 항상 함께 뭉쳐 다니는 모습을 흔히 목격할 수 있다.
    • 이렇게 몰려 다니는 데이터 뭉치는 보금자리를 따로 마련해줘야 마땅하다.

3.12 반복되는 switch문

  • 중복된 switch문이 문제가 되는 이유는 조건절을 하나 추가할 때마다 다른 switch문들도 모두 찾아서 함께 수정해야 하기 때문이다. 이럴 때 다형성은 반복된 switch문이 내뿜는 사악한 기운을 제압하여 코드베이스를 최신 스타일로 바꿔주는 세련된 무기인 셈이다.

3.15 추측성 일반화

  • 이 냄새는 ‘나중에 필요할 거야'라는 생각으로 당장은 필요 없는 모든 종류의 후킹 포인트와 특이 케이스 처리 로직을 작성해둔 코드에서 풍긴다.
    • 그 결과는 물론 이해하거나 관리하기 어려워진 코드다.
    • 당장 걸리적거리는 코드는 눈앞에서 치워버리자.

3.17 메시지 체인

  • 클라이언트가 한 객체를 통해 다른 객체를 얻은 뒤 방금 얻은 객체에 또 다른 객체를 요청하는 식으로, 다른 객체를 요청하는 작업이 연쇄적으로 이어지는 코드를 말한다. ex) managerName = aPerson.department.manager.man;

3.22 데이터 클래스

  • 데이터 클래스란 데이터 필드와 게터/세터 메서드로만 구성된 클래스를 말한다.
  • 그저 데이터 저장 용도로만 쓰이다 보니 다른 클래스가 너무 깊이까지 함부로 다룰 때가 많다.
  • 이런 클래스에 public 필드가 있다면 누가 보기 전에 얼른 레코드 캡슐화하기 로 숨기자. 변경하면 안되는 필드는 세터 제거하기 로 접근을 원천 봉쇄한다.

3.24 주석

  • 주석은 악취가 아닌 향기를 입힌다. 문제는 주석을 탈취제처럼 사용하는데 있다.
  • 주석이 장황하게 달린 원인이 코드를 잘못 작성했기 때문인 경우가 의외로 많다.
  • 주석을 남겨야겠다는 생각이 들면, 가장 먼저 주석이 필요 없는 코드로 리팩토링해본다.

 

 

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

  • 3.4 긴 매개변수 목록에서 매개변수 객체 만들기는 DTO 객체를 만들어서 서비스단으로 전달하는 것과 같다고 생각했습니다.
  • 세터를 줄이는 이유가 가변 데이터의 유효범위를 줄이기 위한다는 걸 알게 되었습니다.
  • 3.17 메시지 체인은 클린코드에서도 봤던 기차충돌 코드와 똑같았습니다.
    • 확실히 메시지 체인 방식의 코드는 가독성을 확 낮춰줍니다.

 

 

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

  • 주석을 어떻게 하면 잘 달 수 있을까?
    • 각자의 스타일이 달라서 제 기준에 주석을 많이 다는 사람도 봤습니다. 어떤게 정답인지 모르겠지만, 저는 이 책에 나오는 얘기처럼 코드에 최대한의 정보를 담고 거기에 담지 못한 정보를 주석으로 남겨야 한다고 생각합니다.

 

 

 
반응형

 

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

  • 리팩터링 [명사] (79p)
    => 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법

  • 리팩터링(하다) [동사] (79p)
    => 소프트웨어의 겉보기 동작은 그대로 유지한 채, 여러 가지 래팩터링 기법을 적용해서 소프트웨어를 재구성하다.

  • 리팩터링은 결국 동작을 보존하는 작은 단계들을 거쳐 코드를 수정하고,
    이러한 단계들을 순차적으로 연결하여 큰 변화를 만들어내는 일이다. (80p)
    • 따라서 래픽터링하는 동안에는 코드가 항상 정상 작동하기 때문에 전체 작업이 끝나지 않았더라도 언제든 멈출 수 있다.

  • 리팩터링은 성능 최적화와 비슷하다. (80p)
    • 둘 다 코드를 변경하지만 프로그램의 전반적인 기능은 그대로 유지한다.
      단지 목적이 다를 뿐이다. 리팩터링은 성능이 좋아질 수도, 나빠질 수도 있다.
  • 나는 소프트웨어를 개발할 때 목적이 ‘기능 추가’냐, 아니면 ‘리팩터링’이냐를 명확히 구분해 작업한다. (81p)
    • 기능을 추가할 때는 ‘기능 추가’ 모자를 쓴 다음 기존 코드는 절대 건드리지 않고 새 기능을 추가하기만 한다.
      진척도는 테스트를 추가해서 통과하는지 확인하는 방식으로 측정한다.

  • 반면 리팩터링 할 때는 ‘리팩터링’ 모자를 쓴 다음 기능 추가는 절대 하지 않기로 다짐한 뒤 오로지 코드 재구성에만 전념한다. (81p)
    • 테스트도 새로 만들지 않는다.
    • 부득이 인터페이스를 변경해야 할 때만 기존 테스트를 수정한다.

  • 같은일을 하더라도 설계가 나쁘면 코드가 길어지기 십상이다. (82p)
    • 사실상 같은 일을 하는 코드가 여러 곳에 나타날 수 있기 때문이다. 그래서 중복 코드 제거는 설계 개선 작업의 중요한 한 축을 차지한다.
    • 코드가 길수록 실수 없이 수정하기 어려워진다.
    • 이해해야 할 코드량도 늘어난다.
  • 프로그래밍은 여러 면에서 마치 컴퓨터와 대화하는 것과 같다. (82p)
  • 프로그래밍은 결국 내가 원하는 바를 정확히 표현하는 일이다. (82p)
  • 문제는 프로그램을 동작시키는 데만 신경 쓰다 보면 나중에 그 코드를 다룰 개발자를 배려하지 못한다는 데 있다. (82p)
  • 코드가 명확하면 버그를 만들 가능성도 줄고, 버그를 만들더라도 디버깅하기 훨씬 쉽다. (84p)
  • 나는 코드를 파악할 때마다 그 코드의 의도가 더 명확하게 드러나도록 리팩터링할 여지는 없는지 찾아본다. (86p)
    • 조건부 로직의 구조가 이상하지 않은지 살펴보기도 하고, 함수 이름을 잘못 정해서 실제로 하는 일을 파악하는 데
      시간이 오래 걸리지는 않는지도 살펴본다.
  • 보기 싫은 코드를 발견하면 리팩터링하자. 그런데 잘 작성된 코드 역시 수많은 리팩터링을 거쳐야 한다. (88p)

  • 오랫동안 사람들은 소프트웨어 개발이란 뭔가 ‘추가’하는 과정으로 여겼다.
    기능을 추가하다 보면 대게 새로운 코드를 작성해 넣게 된다. 하지만 뛰어난 개발자는 새 기능을 추가하기 쉽도록 코드를 ‘수정’하는 것이 그 기능을 가장 빠르게 추가하는 길일 수 있음을 안다. (88p)

  • 리팩터링의 궁극적인 목적은 개발 속도를 높여서, 더 적은 노력으로 더 많은 가치를 창출하는 것이다. ( 92p)
  • 리팩터링의 본질은 코드베이스를 예쁘게 꾸미는데 있지 않다. 오로지 경제적인 이유로 하는 것이다. (93p)
    • 리팩터링은 개발 기간을 단축하고자 하는 것이다.
    • 기능 추가 시간을 줄이고, 버그 수정 시간을 줄여준다.
  • 테스트 주기가 짧다면 단 몇 줄만 비교하면 되며,
    문제를 일으킨 부분이 그 몇 줄 안에 있기 때문에 버그를 훨씬 쉽게 찾을 수 있다. (97p)

  • 자가 테스트코드와 리팩터링을 묶어서 테스트 주도 개발(Test-Driven Development, TDD)이라 한다. (102p)

  • 하드 리얼타임 시스템을 제외한 소프트웨어를 빠르게 만드는 비결은,
    먼저 튜닝하기 쉽게 만들고 나서 원하는 속도가 나게끔 튜닝하는 것이다. (103p)

  • 리팩터링을 자동화하는 가장 어설픈 방법은 소스 코드의 텍스트를 직접 조작하는 것이다. (109p)
    • 리팩터링 도구를 사용해서 리팩터링 진행 (ex. 인텔리제이 IDEA)

 

 

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

  • 현재 리팩터링을 하고 있는 자그마한 프로젝트가 있는데 거기서 제가 진행하는 리팩터링의 경계가 모호했다는 것을 알게되었습니다.
    • 기능을 추가할 때도 있고, 테스트 코드를 대거 수정할 때도 있었습니다.
      이 책을 읽고 명확하게 어떻게 하는 것이 리팩터링이고 기능 추가인지 알게 되었습니다.
  • 리팩터링은 다른 개발자가 내가 작성한 코드를 보다 쉽게 이해하게 도와준다.
    • 내가 작성한 코드를 다른 개발자가 쉽게 이해하게 한다는 것은 결국 시간을 단축시켜준다.
    • 시간을 단축시키면서 회사는 그만큼의 이득을 취하게 된다.
  • 내가 작성한 글도 이 책을 다시 읽으면서 리팩터링 해보는 것은 어떨까 생각했습니다.
  • 리팩터링은 기능을 구현 할 때도 꾸준히 계속 진행해야 한다는 것을 알게되었습니다.
    • ‘구현을 완료하고 리팩터링을 하자’ 라는 생각이 이 책을 읽기 전까지는 가지고 있었습니다.
  • 테스트 코드 하나도 없고 레거시가 줄비한 코드가 적힌 회사에 파견을 나와있습니다.
    • 여기서 문제점은 이런 레거시 코드를 개선하거나 테스트 코드를 추가할 생각을,
      해당 회사 혹은 해당 회사의 개발자가 절대로 하지 않는다는 것 입니다.
  • 인텔리제이 도구를 제대로 사용하지 못하고 있다는 것을 알게되었습니다.
    • 리팩터링을 할 때 인텔리제이를 적극적으로 사용해서 진행

 

 

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

  • 리팩터링의 소중함을 무시하고 이해하기 어려운 코드를 짜는 개발자와는 어떻게 일 할까?
  • 무조건 커밋을 세세하게 분리하는게 정답은 아닌지?
    • 명확한 이유에서 커밋을 세세하게 분리해야 한다는 걸 이책으로 알게 되었습니다.
    • 단순히 커밋을 세세하게 분리해야 한다는 생각으로 분리하면 안된다.
  • 데이터베이스 관련 리팩터링은 전반적으로 이해도가 부족해서 읽기 힘들었습니다. (99P)
    • 아직 공부가 덜 된 것이라고 생각합니다. 차 후에 무조건 다시 읽어야 할 부분입니다.

 

 

반응형

 

 

 

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

  • 리팩터링이란?(7p)
    겉으로 드러나는 코드의 기능(겉보기 동작)은 바꾸지 않으면서 내부 구조를 개선하는 방식으로
    소프트웨어 시스템을 수정하는 과정이다.

  • 프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 쉬운 형태로 리팩터링하고 나서 원하는 기능을 추가한다.(27p)

  • 리팩터링하기 전에 제대로 된 테스트부터 마련한다. 테스트는 반드시 자가진단하도록 만든다.(28p)

  • 조금씩 수정하여 피드백 주기를 짧게 가져가는 습관이 이러한 재앙을 피하는 길이다.(32p)

  • 리팩터링은 프로그램 수정을 작은 단계로 나눠 진행한다.
    그래서 중간에 실수하더라도 버그를 쉽게 찾을 수 있다.(32p)

  • 하나의 리팩터링을 문제없이 끝낼 때마다 커밋한다.
    그래야 중간에 문제가 생기더라도 이전의 정상 상태로 쉽게 돌아갈 수 있다.(33p)

  • 컴퓨터가 이해하는 코드는 바보도 작성할 수 있다.
    사람이 이해하도록 작성하는 프로그래머가 진정한 실력자다.(35p)

  • 임시 변수는 나중에 문제를 일으킬 수 있다. 임시 변수는 자신이 속한 루틴에서만 의미가 있어서 루틴이 길고 복잡해지기 쉽다.(42p)
    • 함수를 직접 선언해 사용하도록 바꾼다.

  • 긴 함수를 작게 쪼개는 리팩터링은 이름을 잘 지어야만 효과가 있다.(44p)
    • 처음에는 당장 떠오르는 최선의 이름을 사용하다가 나중에 더 좋은 이름이 떠오를 때 바꾸는 식이 좋다.
      흔히 코드를 두 번 이상 읽고 나서야 가장 적합한 이름이 떠오르곤 한다.

  • 리팩터링은 대부분 코드가 하는 일을 파악하는 데서 시작한다.(76p)
  • 좋은 코드를 가늠하는 확실한 방법은 ‘얼마나 수정하기 쉬운가’다(76p)

 

 

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

  • 리팩터링을 하기 위해서는 테스트 코드들 부터 마련해야 한다는 말이 정말 공감됩니다.
    저자의 말대로 사람은 실수를 할 수 있기 때문에 테스트 코드를 통해 수정된 코드를 검증 할 수 있습니다.(28p)

  • 변수명을 축약해서 작성한 것을 많이 봤습니다.
    해당 프로젝트를 진행 할 때 변수명의 의미를 파악하는데 시간을 상당히 많이 소비했습니다.

  • perf라는 변수는 해당 코드를 처음보면 무슨 의미인지 알기 힘들 것 같다고 느꼈습니다.

  • 깃에 커밋 푸쉬를 하는데 코드를 뭉텅이로 하는 사람을 봤습니다.
    결국에 그 사람은 버그가 생겼을 때 해당 버그를 찾는데 엄청난 시간을 쏟았습니다.
    커밋을 잘게 나누는게 정말 중요하다고 느낀 계기였습니다.

  • 책이 되게 친절하게 잘 적혀있었습니다.
    하나의 함수로 작성된 코드를 리팩터링 한 부분을 화살표로 표시해준게 정말 좋았습니다.

 

 

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

  • 대규모 프로젝트에서는 어떻게 리팩터링을 진행하는지 궁금했습니다.
  • 변수명을 축약해서 나타내는 회사들이 많습니다.
    전문용어들의 의미를 변수명에 담을려고 하니까 그렇지 않을까 생각했습니다.
    이런 문제를 어떻게하면 더 좋게 해결할지 궁금했습니다.

  • 얕은 복사와 깊은 복사를 한번 배웠었는데 리팩터링에도 같은 내용이 나왔습니다.
    하지만 해당 내용에 대해 아직 이해가 덜 되어서 이해하는데 조금 힘이 들었습니다.
  • 다형성 부분은 한번 더 봐야 할 것 같습니다.

 

 

반응형

+ Recent posts