Home

[Develop] 훌륭한 프로그래머 되는 법 [ Part2. 연습을 통해서 완벽해진다 ]

훌륭한 프로그래머 되기

훌륭한 프로그래머 되는 법

날짜: 2019.09.11 ~ 09.26

Part2. 연습을 통해 완벽해진다

목차

  1. 소프트웨어 개발이란
  2. 규칙 가지고 놀기
  3. 간결하게 하기
  4. 머리쓰기
  5. 변하지 않는 것은 없다
  6. 코드 재사용 사례
  7. 효과적인 버전 관리
  8. 골키퍼 있다고 골 안들어가랴
  9. 동결된 코드의 신비한 사례
  10. 제발 저를 배포해 주세요

소프트웨어 개발이란

  • 이번 파트는 개발이란 무엇이며 다른 일과 빗대어 이를 설명하고 있다.
  • 개발 = 예술/과학/스포츠/놀이/집안일 이다.

    • 에술: 창조력, 미학적, 기계적/수동적, 팀 기반
    • 과학: 엄격함, 체계화, 통찰력
    • 스포츠: 팀워크, 훈련, 규칙
    • 놀이: 학습, 단순함, 즐기기
    • 집안일: 청소하기, 보이지 않는 곳에서 일하기, 작업하기, 유지보수

규칙 가지고 놀기

  • 이번 파트는 규칙이 왜 필요하며, 어떤 규칙을 만들어야 하는지 설명하고 있다.
  • 규칙의 필요성

    • 규칙은 일을 수월하게 해준다.
    • 규칙은 안전을 보장한다.
    • 규칙은 사회적 규범을 규정한다.
  • 일반적인 규칙(코딩 스타일, 일하는 방법)을 제외하고서도 더 많은 규칙이 필요하다.
  • 팀에서 좋은 플레이가 되는 방법과 같은 코딩문화를 설명하는 규칙이 예이다.

    • 책에서 나온 예시

      1. 간결하게 하라
      2. 머리를 쓰라
      3. 변하지 않는 것은 없다
  • 현재 일하고 있는 곳에서의 규칙을 확인하고 이를 재정의 해보라.

간결하게 하기

  • 단순함은 의심할 여지 없이 훌륭한 목표이며 코드에서 이를 확실하게 추구해야한다.
  • 개발자 세상에서 잘못된 방향과 좋은 방향의 간결함이 존재 한다.

    • 잘못된 방향의 간결함은 다음과 같다.

      1. 그냥 단순하게 하려 한다. 머리를 쓰지 않는다.
      2. 복잡한 부분은 생략하고, 다루기 힘든 부분은 무시하려 한다.
      3. 간결함은 넘어 단순한 코드가 되지 말자. 단순한 코드는 올바르지 않다.
  • 코드를 간결하게 만드는 것은 엄청나게 어려운 작업이다.
  • 간결한 설계란 무엇인가?

    1. 사용이 간편하다
    2. 오용을 방지한다.
    3. 복잡한 부분을 적절하게 위치 시킴으로서 코드를 간결하게 할 수 있다.
    4. 크가기 적절하다.
    5. 가능한 작게, 원자 수준으로 이루어 져야 한다.
    6. 짧은 코드 경로
    7. 간결한 설계는 우회를 줄여주고 기능과 데이터가 필요한 곳에 있다.
    8. 안정성
    9. 많은 양의 코드를 고쳐쓰지 않고도 개선/확장 할 수 있다.
    10. 간결한 인터페이스는 안정적이고 잘 바뀌지 않는다.
  • 코드를 간결하게 작성 하는 방법

    1. 일관성있게 작성하라.
    2. 애매한 코드를 작성하지 말라.
    3. 오류를 발견할 경우 반창고만 붙이는 치료를 하지 말고, 코드를 재작성하는 것을 목표로 하라.
    4. 불필요한 가설을 세우지 말라. 가설은 코드를 이해하기 위한 추가 정보를 요구 한다.
    5. 너무 이른 최적화를 하지 말라.
    6. 충분하게 간결하게 작성하라
    7. 가장 간결한 방법으로 작업하고 가장 간결한 코드를 작성하라.
    8. 문제를 해결하기 위해 딱 필요한 양의 코드를 작성하라
    9. 지나치게 복잡한 해결책을 내놓지 말라.

머리쓰기

  • 바보짓을 하지 말라

    • 코드에서 명백한 사실을 놓치지 않도록 해라
    • 지나치게 복잡한 설계를 하지 말라
    • 쉽게 피할수 있는 멍청함을 코드에 더하지 말라
    • 실수를 했다면 이를 인정하고 해결 하라
  • 어리석은 습관성 행동을 피하라

    • 코드를 작성할 때마다, 일단 작업은 멈추고 정신을 차린 뒤 대안이 있는지 확인해봐라. 대안을 확인해 보지 않은 탓에 처음 세운 계획을 고집하고 있는 것은 아닌지 되돌아 보아라
    • 주의를 기울여라. 부주의하게 코드를 작성하지 말라
  • 코드는 기계적으로 해서는 안된다. 머리를 써라
  • 특정 코드 영역에서 작업할 때 그 모양과 구조에 관해 의식적으로 결단을 내려라
  • 그 어떤 개선이나 변화가 요구되든 간에, 그에 관한 결정을 내림에 있어서 능동적이 되라
  • 가차없는 수정이 필요한 누더기 코드를 발견 했을 때는 거기에 또 다른 누더기 코드를 덧 씌우지 말라

이번 챕터는 코드를 작성할때 항상 생각 하고 고민해야 한다는 것을 강조 하고 있다. 나 같은 경우 코드를 작성할 때 가끔 무의식적으로 코드를 작성하고 있는 것 같다. 무의식적으로 코드를 작성하지 않고 항상 한줄 한줄 작성할 때마다 생각하는 습관을 들여야 할 것 같다.

변하지 않는 것은 없다

  • 코드 수정을 두려워 해서는 안된다. 두려움은 잘못될지도 모른다는 두려움과 추가 업무, 수정 비용, 일정등에서 딸려 오게 되어 있다. 하지만 이를 두려워 해서는 안되다. 또한 완벽하게 알지 못하는 코드를 바꿔야 할때 불안감을 느끼기도 한다
  • 소프트웨어는 단단한 것이 아니라 부드러워야 한다
  • 코드란 절대 불변이어서는 안되며, 그 어떤 코드도 신성시 되어서는 안된다
  • 만약 코드가 구속복이 되버리면, 더 이상 소프트웨어를 개선한다고 볼 수 없으며 코드에 맞서 싸우는 형태가 되버린다
  • 용감한 수정

    • 어떻게 하면 오류에 대한 두려움 속에서도 용기있게 수정할 수 있을까?

      1. 좋은 수정을 가하는 방법을 배운다
      2. 소프트웨어를 쉽게 바꿀 수 있게 만드는 것이 무언인지를 배우고, 이런 특성을 가진 소프트웨어를 만들기 위해 노력한다
      3. 매일 코드를 개선하며 더욱 수정이 용이한 상태로 만들라. 코드의 품질에 대해서는 타협을 거부하라
      4. 건강한 코드를 이끄는 건강한 태도를 포용하라
    • 시도하는 것은 부끄러운 것이 아니며, 실수로부터 항상 배울 수 있다. 다만 그 어떠한 수정에 대해서도 출시 이전에 충분한 테스트와 검증을 거쳤음을 보장하라
  • 태도 바꾸기

    • 코드 수정시 겁쟁이 같은 접근법을 취한다면 목표에 이르지 못한다
    • 좋은 코드는 다른 사람의 문제가 아니다. 자신의 책임이다
  • 수정하기

    • 코드를 수정할때 적절한 지점, 방식을 찾는 법을 배워야 한다. 목적지를 향할때 국도로 갈것인지 고속도로 갈것인지는 시작 위치에서 달라질 수 있다
    • 코드속을 돌아다니는 길을 찾아내는 방법을 배우는 것이다. 부작용이 숨어있는 곳을 지도에서 찾고, 따라가고, 부작용이 튀어나오는 지점을 파악하는 것이다
  • 수정을 위한 설계

    • 두가지 기능을 하는 함수는 두 부분으로 나누어라
    • 함축적인 것은 명백하게 하라
    • 융통성이 없는 결합과 불필요한 복잡함을 피하라
    • 매일 매일 천천히 안전하게 단편적으로 코드를 개선하라
    • 한번에 전체 코드베이스와 싸우려 하지 말라. 위협적이고, 고치기 어려운 일이 될것이다
    • 많은 것을 동시에 처리하지 말고 하나씩 처리하라

이번 챕터는 코드 수정에 겁먹지 말라는 것이다. 나같은 경우에도 다른 사람이 작성한 코드를 수정하는데 겁부터 내곤 하였다. 물론 지금도 돈과 관련된 부분을 수정할때는 겁이 나긴 하지만 그래도 한번 하고 나니깐 크게 겁을 먹을 필요가 없다는 것을 배웠다. 특히 이번 챕터는 정산 리뉴얼을 하기전에 보았으면 좋았을것 같다. 잘만든 코드에 내가 똥을 싸논 느낌이지만 조금씩 리팩토링을 해나가야 할것이다.

코드 재사용 사례

  • 복사&붙여넣기

    • 자신이 했던일을 반복하지 말라. (Do not repeat yourself)
    • 복사&붙여넣기는 더러운 행위이며, 자존심 있는 프로그래머라면 이런 종류의 코드 재사용은 하지 않는다
    • 또한 복사&붙여넣기는 버그를 복제하며, 만약 복사한 코드에 버그가 있다면 복사한 수만큼 수정을 해야한다. 이런 경우라면 공통 함수와 공통 라이브러리에 넣어 사용하라
    • 웹에서 찾은 코드를 함부로 사용하지 말라. 테스트를 하였는지, 검증된 코드인지, 사용해도 되는 코드인지 확인하고 이를 사용하라
  • 재사용을 위한 설계

    • 코드가 하나의 프로젝트가 아닌 더 많은 용도로 사용될 것인지 의심스러운 상황에서, 처음부터 다양하게 사용될 수 있도록 처리하는 것은 가치 없는 일이다
    • 아직 필요하지 않으면 작성하지 말라
    • 당장의 요구사항을 모두 만족시킬 수 있는 가장 간단한 코드를 만드는 데에만 집중하라
    • 가능한 가장 적은 양의 소프트웨어를 만듦으로써, 버그를 양산하거나 향후 수년간 지원해야 하는 불필요한 API를 만들 위험을 줄일수 있다
  • 리팩토링 하기

    • 작고 모듈화된 코드를 작성하라
    • 깨끗하고 정돈된 상태를 유지하라
    • 한 곳이 아닌 여러곳에서 사용되는 시점에 코드를 리팩토링 하라
    • 수정을 최소화하고 단순화 하는 것에만 집중한다
  • 매입하라. 아니면 시간낭비이다

    • 새로운 기능을 추가해야 할 때, 라이브러리를 쓸 것인지, 아니면 직접 개발할 것인지 고민 할 수 있다. 어느게 더 경제적인지 고민하고 사용할때는 검증하라. 직접 개발하는 것은 시간낭비 일 수 있다.

이번 챕터는 재사용에 관한 이야기를 하고 있다. 이번 챕터에서 상당히 준요한것은 반복하지 말것과 여러곳에 사용되는 시점에 코드를 리팩토링 하라 라는 구절 같다. 나같은 경우 같은 기능을 하는 코드를 가끔 복사&붙여넣기를 사용하기도 하고 리팩토링을 하지 않고 커밋을 하는 경우도 있었다. 일단 동작되는 코드를 작성후 커밋을 다시 살펴봐 코드를 정리하는 법을 습관화 해야 할 것이다.

효과적인 버전 관리

  • 좋은 버전 관리 도구를 잘 사용한다면 다음과 같은 이점이 있다

    1. 협업의 중심으로서 개발자들 간의 협력을 조율한다
    2. 최신의 상태를 정의하고 게재한다
    3. 프로젝트 내에서 이루어진 작업의 기록을 유지하고, 각 배포 버전에 포함되어야 하는 정확한 콘텐츠들을 모아둔다. 이는 코드에 대한 타임머신이라 할 수 있다
    4. 소프트웨어 고고학을 시행할 수 있다. 특정 기능을 구성하는 변경 사항을 확인하기 위해 파일들의 변경 명세를 추적할 수 있다
    5. 작업에 대한 중추적인 백업 도구로서의 역활을 한다
    6. 개발자에게 안전망을 제공한다
    7. 작업에 운율과 박자를 제공한다. 개발 -> 테스트 -> 체크인이 반복되는 형태가 된다
    8. 하나의 코드 베이스에서 동시에 여러 개의 방향으로 개발을 수행할 수 있게 한다
    9. 작업을 되돌릴 수 있다
  • 버전 관리는 프로젝트 시작 시점부터 적용하라. 예외는 없다
  • 버전 관리 도구는 단순히 사용하면 좋은 도구가 아니다. 버전 관리 도구야말로 개발의 중추이다
  • 버전 관리 도구는 다양하다. 어떤 것이든 좋으니 하나를 골라서 사용하라

    • 버전 관리 도구는 중앙 집중화 방식, 분산 방식으로 나누어진다
  • 체크인할 때에는 적절한 것을 저장하라. 다음과 같은 것들을 저장해야 할 것이다

    1. 모든 소스 코드 파일
    2. 모든 문서
    3. 모든 빌드 파일
    4. 모든 설정 파일
    5. 모든 자원
    6. 모든 서드파티 제공 파일
  • 혼란을 초래하거나 쓸데없이 용량을 늘리거나 방해가 되는 불필요한 것들은 제외하라

    1. IDE 설정 파일이나 캐시 파일
    2. 자동 생성된 파일
    3. 프로젝트 일부가 아닌 것들
    4. 테스트 보고서나 버그 보고서
    5. 흥미로운 프로젝트 관련 이메일
    6. 개인적인 설정
    7. 언젠가는 필요할 것이라 여겨지는 것들
  • 저장소의 Layout에 대해 주의 깊게 고민하라

    • 디렉터리 구조가 명확해지도록 코드의 형태를 드러내라
    • 디렉터리 최상단에 ‘READE ME’ 파일을 추가하라
    • 복제는 철저히 피하라
    • 서드파티 파일을 주의 깊게 관리하라
  • 작고 원자적인 커밋(한 번에 하나의 주제만을 다루는 커밋)을 수행하라. 그래야 이해하기 쉽고 적절성을 판별하기 더 쉽다
  • 자주 조금씩 변경사항을 체크인하라. 한꺼번에 체크인하면 다음과 같은 문제를 초래한다

    1. 코드에 발생하는 변경사항을 추적하기 어렵다
    2. 본인이 작업했던 체크인과 현재 작업 중인 체크인 사이에 다른 사람들에 의해 많은 변경이 이루어졌을 수 있다
    3. 주변 환경이 변한다면 더 많은 충돌이 있을 수 있다
  • 원자적 커밋은 응집성이 있고, 일관되어 있어서, 서로 연관된 변경사항들을 하나의 단계로 나타낸다. 한 번에 두 가지 이상의 변경사항을 다뤄서는 안 된다
  • 원자적 커밋은 완결적이어야 한다. 완결되지 않은 작업으로 체크인하지 말라
  • 커밋 메시지는 명확하고 간결하며 모호하지 않게, 좋은 코드를 작성할 때처럼 작성하라
  • 버전 관리 도구 사이를 자주 옮겨서는 안 된다. 저장소에 기록되는 리비전 기록은 가치 있기 때문이다
  • 버전 관리는 핵심적인 소프트웨어 개발 도구이다. 버전 관리 도구를 잘 다루는 방법도 반드시 알아야 한다

이번 챕터는 버전전 관리 도구의 중요성에 관해서 설명하고 있다. 사내에서는 Git을 쓰고 있는데 스터디도 한번 진행하였지만 아직도 단순히 checkout, checkIn, push, pull, merge 정도만을 사용하고 있는 것 같다. 사실 다른 기능을 사용할 이유가 없기도 하지만 그래도 Commit 단장하거나 Rebase를 쓰는 연습도 하고 있다. 책에서 말 한 것처럼 잘 다루는 방법을 조금 더 공부해야 할 것 같다.

골키퍼 있다고 골 안들어가랴

  • QA는 개발자들이 자신들에게 쓰레기를 던진다고 생각하지 잘 포장한 선물을 넘겨준다고 생각하지 않는다
  • 소프트웨어를 QA팀에게 던져버려서는 안 되며 지속적인 의사소통을 추구해야 한다
  • QA는 결함을 찾아내 물건을 망가뜨리고, 개발자들에게 지옥을 맛보게 하려는 것이 아니다. 그들은 최종 산출물을 개선하려는 목적으로 업무를 수행하고 있다
  • 품질 보장 업무는 개발자들과 테스터들이 긴밀히 연계될 때 비로소 효과적으로 수행될 수 있다
  • 개발자와 QA는 같은 편이다
  • 팀 구조가 코드에 영향을 미치는 것과 마찬가지 방식으로 의사소통의 건전성 역시 소프트웨어에 영향을 미친다
  • 개발자는 반드시 QA와 좋은 관계를 유지해야 하며, 우정과 동지애를 가져야 한다
  • QA에게 소프트웨어를 전달할 때 코드전달은 완벽해야 한다. 코드는 책임감 있게 작성하고 사려 깊게 배포해야 한다

    • 배포 빌드를 만들기에 앞서 자신의 결과물이 정확하게 구현되었음을 증명하는 테스트를 실시 해야한다
    • 테스트들은 철저하고 전형적이어야 한다. QA에서 보고하는 그 어떠한 오류도 대응할 수 있는 유닛테스트를 추가하고, 수정한 뒤에 다시 나타나지 않도록 해야 한다
    • QA에게 전달할 때 새 기능을 어떻게 구현했고, 구현하지 않은 것은 어떤 것인지 명확하게 설명하라. 어디서부터 어디까지 작동하는지에 대한 정보가 없는 이상 QA팀에서는 어떤 테스트가 필요한지 어렵다. 배포 메모를 이용하여 QA에게 전달하라
    • 빌드를 너무 급하게 해서는 안 된다. 모든 것을 철저히 확인해야 한다
    • 수작업 절차를 자동화하면 언제나 인간 오류의 가능성을 제거 할 수 있다. 그러므로 빌드나 배포를 최대한 자동화하라
  • QA는 버그를 찾아낼 뿐이다. 버그에 관한 직접적인 책임자가 누구인지는 그들과 상관없다. 진정 프로다운 태도는 제품 전체에 대해 책임 의식을 가지는 것이다. 코드베이스에서 자신이 담당한 부분에 대해서만 책임지려 해서는 안 된다

이번 챕터는 QA에 임하는 개발자의 태도에 관해서 말하고 있다. 사실 현재 회사는 큰 기능을 제외하고는 QA를 진행하지 않아서 많이 접할 기회는 없는데 가끔은 위에서 말한것 처럼 그냥 던저버리는 행동을 한 적이 있는 것 같다. 많이 반성한다. QA팀은 말 그대로 똥덩어리를 받은 느낌일 것이다. 일정에 쫓겨서 던지기는 하였지만 참.. 이렇게 작성된 코드를 다시 보면 정말 형편 없다. 퀄리티를 위해서라도 이런 행동을 하면 안될것이다.

동결된 코드의 신비한 사례

  • 코드 동결은 완료 시점과 출시일 시점 사이의 기간을 나타낸다. 완료 시점이란 더이상 추가 작업을 수행할 필요가 없는 때를 의미한다
  • 코드 동결이라 말하지만, 코드가 더이상 수정될 수 없음을 뜻하는 것은 아니다. 코드에는 어떠한 일이든 일어날 수 있다
  • 코드 동결은 변경을 완전히 막는다기보다는 개발 작업에 대해 새로운 규칙을 적용한다는 의미에 가깝다. 코드에 대한 변경을 무턱대고 적용할 수 없다는 뜻이다. 변경은 신중한 합의 이후 진행한다
  • 동결의 형태

    • 기능 동결
    • 버그에 대해서만 수정을 허용할 뿐 새로운 기능은 개발하지 않는다
    • 코드 동결
    • 우선순위가 높지 않은 기능이나 버그에 대해서는 작업하지 않는다
    • 단단한 코드 동결
    • 변경을 일절 허용하지 않는다
  • 코드 동결을 선언할 때는 보통 버전 관리 시스템에서 코드를 분기한다. 출시 분기를 만드는 것이다
  • 출시 분기 상에서는 절대로 작업하지 않는 것이 최선이다
  • 출시 분기를 만들 때에는 다음과 같이 엄격한 절차를 따라야 한다

    • 모든 변경사항을 신중하게 검토한다
    • 더 집중적인 테스트를 거친다
    • 위험성을 분석하는 만큼, 잠재적인 차이를 잘 이해하고 필요한 경우에는 차이점을 완화한다
    • 각 변경사항에 대해 우선순위를 설정한다. 출시에 적합한지를 신중히 검토한다
  • 코드 동결이라는 명명에 현혹되지 말라. 코드는 언제든 변경될 수 있다
  • 코드 동결 기간 동안, 위험을 감수하고 수정해야 할 만큼 중요하지 않은 버그들이 발견될 수 있다. 이는 더 이상의 자유로운 코드 변경이 불가능하다는 것을 의미한다. 그렇지 않다면 동결을 선언해서는 안 된다
  • 더 낫게 만들 수도 있는 소프트웨어를 그냥 배포하는 일이 이상한 일은 아니다. 그렇다고 잘못된 일도 아니다
  • 코드 동결 기간에는 기술적 부채가 발생할 수 있다. 부채의 발생을 감시하고 배포 이후에 곧바로 갚을 준비를 해라.

이번 챕터는 코드 동결에 대해서 말하고 있다. 그런데 사실 깊게 와닿지 못하였다. 지금 회사는 개발이 끝나고 QA가 끝나면 바로 배포 하는 프로세스를 가지고 있다. 물론 공유일전이나 금요일 같은 경우에는 배포 금지이므로 이 기간을 코드 동결 기간이라 볼수 있지만 사실상 해당 기간에는 일을 하지 않는 기간이므로 의미가 없다 볼 수 있다. 그냥 이런 개념이 있구나.. 아니면 대기업에서는 이런식으로 일하는 구나 정도로만 생각 하였다.

제발 저를 배포해 주세요

  • 배포 버전을 만드는 과정에는 규율과 계획이 필요하다. 개발자의 IDE에서 ‘빌드’ 버튼을 누르는 것만으로는 충분하지 않다
  • 효율적인 배포를 위해서는 다음 3가지 요소가 필요하다

    • 단순함
    • 반복 가능함
    • 신뢰할 수 있음
  • 배포 버전을 만들 때는 다음과 같은 사항을 수행해야 한다

    • 정확하게 똑같이 빌드할 수 있는, 정확히 똑같은 코드를 소스 관리 시스템에서 받을 수 있는지 확인하라
    • 어떻게 빌드하는지를 정확하게 기록하라
    • 나중에 참조 할 수 있도록 빌드 로그를 캡처하라
  • 배포 버전을 만들 때는 항상 새로운 체크아웃에서 빌드하라. 기존에 사용하던 빌드의 일부분을 다시 사용하는 일이 절대 없어야 한다
  • 빌드는 자동화되어야 한다. 이를 위해 스크립트 언어를 사용하라
  • 빌드의 건전성을 보장하기 위해 CI서버를 적용하라. 동일한 시스템에서 공식적인 배포 버전을 만들라
  • 과거의 배포 버전과 이번 배포 버전이 어떻게 다른지 묘사하는 일련의 배포 노트를 만들라. 여기에는 새로운 기능과 수정된 버그들의 목록을 포함해라
  • 최종 결과물을 테스트하지 않았더라면 배포해서는 안 된다
  • 자동화 빌드 및 배포 설비를 구축하는 시점은 개발 과정 중 이른 초기에 이루어져야 한다

2장 마지막 챕터에는 배포에 대해서 말하고 있다. 지금 회사는 Push 만해도 테스트가 동작하고, Merge를 할 경우에도 마찬가지로 테스트가 동작한다. 또한 모든 과정이 자동화 되어 있기때문에 테스트가 깨지는지, EC2에 배포가 잘되었는지만 확인하면 된다. 또한 Commit 로그를 일종의 배포 노트로 사용하며, 배포가 완료되면 슬랙으로 알람이 와서 어떤 배포가 되었는지 배포자가 간단한 노트를 남기는 형식으로 일을하고 있다. 이게 상당히 편한데 이런 자동화를 지속적으로 유지하고 어떻게 구축하였는지 한번 살편 볼만 하다.

Loading script...