Introduction
- "작은 커밋이 너무 작은 건 아닐까?"
- "이런 코드는 어디에 넣어야 하지?"
- "이 부분까지 테스트해야 할까?"
개발자라면 누구나 한 번쯤 이런 고민을 해보셨을 겁니다. 저 역시 그랬고요. 클린 코드, SOLID 원칙, TDD... 수많은 개발 원칙과 방법론 속에서 올바른 길을 찾으려 애쓰다 보면 어느새 지쳐있는 자신을 발견하게 됩니다.
하지만 이 글에서 전하는 놀라운 사실은, 정작 제품의 품질을 높이고 개발 속도를 끌어올린 건 거창한 개발 원칙이 아닌 소소한 '습관들'이었다는 점이었다는데요. 해커뉴스에서 화제가 된 이 글 <Good software development habits>에서는 저자가 실제로 실천하고 있는 10가지 개발 습관을 공유하려고 합니다.
켄트 벡의 말처럼 "변경을 쉽게 만든 다음, 쉬워진 변경을 하라"는 게 전부입니다. 더 이상 복잡하게 생각하지 마세요. 이제부터 놀라울 정도로 단순하지만 효과적인 10가지 개발 습관을 소개합니다.
Good software development habits
이 글은 조언이 아닌, 제가 실천하고 있는 방법들입니다.
나쁜 습관은 쉽게 들지만 좋은 습관을 만들기는 어렵습니다. 효과적인 방법들을 기록해두면 열심히 들인 좋은 습관을 유지하는 데 도움이 됩니다. 현재 개발 중인 제품의 개발 속도를 높이고 품질을 유지하는 데 도움이 된 10가지 방법을 공유합니다.
1. "이 정도로 작게 해도 되나?" 싶을 만큼 커밋을 작게 유지하세요.
특정 변경사항을 되돌려야 할 때가 언제 올지 모르기 때문입니다. 6일 전에 발생한 버그의 정확한 위치를 알고, 복잡한 병합 충돌 없이 해당 커밋만 되돌릴 수 있다는 것은 큰 안도감을 줍니다. 제 기준은 간단합니다. 컴파일이 되는 코드는 커밋할 수 있습니다.
2. 켄트 벡의 금언을 실천하세요: "원하는 변경을 위해 먼저 그 변경을 쉽게 만들고(주의: 이게 어려울 수 있음), 그다음 쉬워진 변경을 하라."
전체 커밋의 절반 이상이 리팩터링이 되도록 하세요. 지속적인 리팩터링이란 10분 이내로 할 수 있는 개선사항을 찾아 적용하는 것입니다. 이런 작은 개선들 덕분에 나중에 큰 요구사항이 들어왔을 때 간단한 변경만으로도 해결할 수 있습니다. 대규모 리팩터링은 피해야 합니다.
3. 모든 코드는 부채입니다.
배포되지 않은 코드는 부채 중의 부채죠. 코드가 제대로 작동하는지, 최소한 다른 기능을 망가뜨리지는 않는지 확인해야 합니다. 테스트는 자신감을 주고, 프로덕션 배포는 검증을 제공합니다. 잦은 배포로 호스팅 비용이 조금 늘어날 수 있지만, 마지막 작업이 실제 진전이었다는 것을 확인할 수 있다는 점에서 충분히 가치가 있습니다. 애자일 원칙 중 하나는 "작동하는 소프트웨어가 진척도의 주요 척도"라고 합니다. 여기서 '작동'과 '진척'이라는 단어가 핵심적인 의미를 가지므로, 제 나름의 정의를 내렸습니다. '작동'이란 배포 가능한 수준을 의미하고, 어떤 기능에 기여하는 코드라면 그것이 '진척'입니다.
4. 프레임워크의 기능을 테스트하고 있는지 자문해보세요. 만약 그렇다면, 하지 마세요.
프레임워크는 이미 당신보다 훨씬 더 전문적인 사람들이 테스트했으며, useState() 훅이 의도한 대로 작동한다고 신뢰해야 합니다. 컴포넌트를 작게 유지하면 프레임워크가 대부분의 핵심 작업을 처리하므로 많은 테스트가 필요 없습니다. 컴포넌트가 커지면 복잡성이 증가하고 그만큼 더 많은 테스트를 작성해야 합니다.
5. 특정 함수가 어디에도 어울리지 않는다면, 새로운 모듈(또는 클래스나 컴포넌트)을 만들고 나중에 적절한 위치를 찾으세요.
어울리지 않는다고 느끼는 곳에 억지로 끼워 넣는 것보다, 새로운 독립적인 구조를 만드는 것이 낫습니다. 최악의 경우라도 독립 모듈로 남는 것이 그리 나쁘지 않습니다.
6. API가 어떤 모습이어야 할지 모르겠다면, 테스트를 먼저 작성하세요.
이는 이 경우 당신 자신인 "고객"의 관점에서 생각하도록 만듭니다. 코드를 먼저 작성하고 나중에 테스트했다면 발견하지 못했을 케이스들을 찾아낼 수 있습니다. TDD에 너무 교조적일 필요는 없으며, 더 큰 단위로 작업해도 괜찮습니다(예: 테스트 통과 전에 여러 줄의 코드를 작성). 실패 상태의 코드 양이 항상 적을 필요는 없습니다. 무엇을 하고 있는지 알고 있다면, 원칙이 생산성을 저해하지 않게 하세요.
7. 복사-붙여넣기는 한 번까지는 괜찮습니다.
두 번째 중복(즉, 세 번째 복사)은 하지 마세요. 이 시점이면 좋은 추상화를 만들 수 있는 충분한 사례가 있을 것입니다. 동일한 기능의 구현이 서로 달라질 위험이 너무 크므로, 통합이 필요합니다. 비슷한 기능을 여러 번 구현하는 것보다는 다소 어색한 매개변수화가 낫습니다. 이런 상황이 다시 발생하면 네 가지 다른 구현을 통합하는 것보다 매개변수를 개선하는 것이 더 쉬울 것입니다.
8. 설계는 낡기 마련입니다.
리팩터링으로 그 속도를 늦출 수는 있지만, 결국에는 작동 방식을 바꿔야 합니다. 예전에 소중하게 여기고 자랑스러워했던 것을 버리게 될 때 너무 마음 아파하지 마세요. 당시에는 최선을 다했고, 변경이 필요 없을 만큼 완벽하게 하지 못했다고 자책할 필요 없습니다. 소프트웨어 개발의 대부분은 소프트웨어를 변경하는 것입니다. 이를 받아들이고 앞으로 나아가세요. 완벽한 설계란 없으며, 변경은 소프트웨어 개발의 핵심입니다. 얼마나 능숙하게 변경할 수 있는지가 개발자로서의 역량을 결정합니다.
9. 기술 부채는 세 가지로 분류할 수 있습니다:
1) 현재 작업을 방해하는 것들, 2) 향후 작업을 방해할 것들, 3) 향후 작업을 방해할 수 있는 것들. 다른 모든 분류는 이 세 가지의 하위 집합입니다. #1에 해당하는 것들을 최소화하고 #2에 집중하세요. #3은 신경 쓰지 마세요.
10. 테스트 가능성은 좋은 설계와 밀접한 관련이 있습니다.
쉽게 테스트할 수 없다는 것은 설계를 변경해야 한다는 신호입니다. 때로는 그 설계가 테스트 설계일 수 있습니다. 예를 들어, em.getRepository(User).findOneOrFail({id})를 모킹하기 어렵다면, 해당 호출을 모킹 가능한 별도의 함수로 분리하거나 엔티티 매니저 메서드를 쉽게 모킹할 수 있는 테스트 유틸리티를 작성하는 것이 좋습니다. 테스트가 작성되지 않는 이유는 테스트하기 싫어서가 아니라 테스트하기 어렵기 때문입니다.
더 많은 내용이 있겠지만, 10가지면 적당해 보이네요. :)
👥 더 나은 데브필을 만드는 데 의견을 보태주세요
Top 1% 개발자로 거듭나기 위한 처방전, DevPill 구독자 여러분 안녕하세요 :)
저는 여러분들이 너무 궁금합니다.
어떤 마음으로 뉴스레터를 구독해주시는지,
어떤 환경에서 최고의 개발자가 되기 위해 고군분투하고 계신지,
제가 드릴 수 있는 도움은 어떤 게 있을지.
아래 설문조사에 참여해주시면 더 나은 콘텐츠를 제작할 수 있도록 힘쓰겠습니다. 설문에 참여해주시는 분들 전원 1개월 유료 멤버십 구독권을 선물드립니다. 유료 멤버십에서는 아래와 같은 혜택이 제공됩니다.
- DevPill과의 1:1 온라인 커피챗
- 멤버십 전용 슬랙 채널 참여권
- 채용 정보 공유 / 스터디 그룹 형성 / 실시간 기술 질의응답
- 이력서/포트폴리오 템플릿
의견을 남겨주세요