GN⁺: 좋은 소프트웨어 개발 습관
(zarar.dev)- 이 글은 조언이 아닌, 저자가 현재 적용하고 있는 개발 습관들에 대해 작성한 내용
- 나쁜 습관을 피하고 좋은 습관을 만들기 위해 노력한 경험을 정리한 글로, 생산성 향상과 품질 유지에 도움이 되었던 10가지 습관을 다룸
1. 작은 커밋 유지
- 커밋을 최대한 작게 유지해야 함. 작은 커밋은 버그 발생 시 특정 커밋만 되돌릴 수 있게 하여, 복잡한 병합 충돌을 피할 수 있음
- "소프트웨어가 컴파일될 때 커밋할 수 있어야 한다"는 것을 규칙으로 삼음
2. 지속적인 리팩토링
- Kent Beck의 조언: "변화를 원할 때, 먼저 변화를 쉽게 만들고, 그런 다음 쉽게 변화를 만드세요."
- 최소 절반의 커밋은 리팩토링이 포함되도록 함. 작은 리팩토링이 큰 요구사항이 들어올 때 큰 도움이 됨
- 큰 리팩토링은 피해야 함. 대신 10분 이내의 작은 개선 작업을 지속적으로 수행
3. 코드 배포의 중요성
- 코드 자체는 잠재적 부채이며, 배포되지 않은 코드는 가장 큰 부채임
- 테스트는 신뢰감을 주지만, 실제 배포는 진정한 승인을 의미함
- 배포 빈도가 높아질수록 호스팅 비용이 증가할 수 있지만, 최신 작업이 실제로 작동함을 확인하는 것은 중요한 이점임
4. 프레임워크의 기능 테스트하지 않기
- 프레임워크의 기능을 테스트하지 않음. 프레임워크는 이미 충분히 검증되어 있음
- 컴포넌트를 작게 유지하면 프레임워크가 대부분의 작업을 처리하게 되어 테스트가 줄어듦
- 큰 컴포넌트는 복잡성을 추가하고, 이에 따라 많은 테스트가 필요해짐
5. 새로운 모듈 생성
- 특정 기능이 기존 모듈에 맞지 않는다면, 새 모듈을 생성하는 것이 좋음
- 기존 모듈에 억지로 기능을 추가하는 것보다 독립적인 모듈로 남겨두는 것이 나음
6. 테스트 주도 개발(TDD)의 유연한 적용
- API 설계가 명확하지 않을 경우 테스트를 먼저 작성하여 "고객"의 입장에서 생각함
- TDD는 종교적인 원칙으로 따르지 않음. 필요한 경우 더 큰 단위로 작업 후 테스트할 수 있음
- 작은 단위의 코드를 실패 상태로 만들지 않아도 되며, 생산성을 저해하는 교조주의에 얽매이지 않음
7. 복붙은 한 번만 허용
- 한 번의 복사는 괜찮지만, 두 번째 복사부터는 중복이 생김
- 이 시점에서 적절한 추상화를 통해 중복을 제거해야 함. 파라미터화가 약간 이상해 보여도, 여러 구현을 합치는 것보다는 나음
8. 디자인의 변화 수용
- 디자인은 시간이 지나면서 낡아짐. 리팩토링을 통해 노화를 늦출 수 있지만 결국에는 바뀔 수밖에 없음
- 이전의 디자인을 너무 집착하지 말고, 변화를 받아들여야 함
- 완벽한 디자인은 없으며, 변화에 잘 대처하는 능력이 소프트웨어 개발의 핵심임
9. 기술 부채의 세 가지 유형
- 기술 부채는 세 가지 유형으로 분류할 수 있음:
- 현재 작업을 방해하는 것
- 미래 작업을 방해할 가능성이 있는 것
- 방해할 가능성이 있을지도 모르는 것
- 첫 번째 유형의 부채는 최소화하고, 두 번째 유형에 집중하며, 세 번째 유형은 무시해야 함
10. 테스트 가능성과 좋은 설계의 관계
- 테스트하기 어렵다면 설계에 문제가 있을 가능성이 높음
- 테스트 설계 또한 개선의 대상이 될 수 있음. 예를 들어,
em.getRepository(User).findOneOrFail({id})
의 목(Mock) 작성을 어렵게 느낀다면, 별도의 함수로 분리하거나 테스트 유틸리티를 사용하는 것이 좋음 - 테스트가 작성되지 않는 이유는 테스트하기 어렵기 때문이며, 이는 설계의 문제일 수 있음
이 글은 원본을 꼭 보시면 좋을 것 같아요.
늘 관심가는 뉴스면 원본을 보곤 하는데 이건 특히나 그러면 좋을 것 같아요 1번을 보면 원글은
Keep commits small enough that you wonder if you're taking this "keep commits small" thing a little too far. 라고 되어있는데 "커밋을 최대한 작게 유지해야 함" 이라고 간추려 졌네요..
얼마나 변화에 빠르게 적응할 수 있는 코드와 환경을 만들었느냐가 제일 중요한 것 같아요.
그리고 적절한 추상화를 통해 코드 재사용성과 확장성을 높이고, AI 도구를 활용해 개발 속도를 극대화할 수 있어요.
Hacker News 의견
-
여러 구현을 피하기 위해 매개변수를 사용하는 것이 좋음. 매개변수를 개선하는 것이 여러 구현을 통합하는 것보다 쉬움.
- "이상한 매개변수"를 피할 수 없다면, 코드를 분리하는 것이 좋음. 불리언 플래그와 여러 개의 열거형 매개변수를 피해야 함.
- 복잡한 함수 서명은 유지보수를 어렵게 만듦.
-
코드 복사는 한 번은 괜찮지만, 두 번째부터는 중복을 피해야 함. 충분한 데이터 포인트가 있을 때 좋은 추상화를 만들어야 함.
- 코드가 처음에는 같더라도, 변화가 필요할 때 함께 변화해야 하는지에 집중해야 함.
- 코드 중복을 피하는 것이 목표가 아니라, 함께 진화해야 하는 코드를 함께 유지하는 것이 목표임.
-
DRY(반복하지 말라)나 WET(모든 것을 두 번 작성하라)는 절대적인 규칙이 아님. 코드 중복과 통합의 시점을 이해하는 것이 어려운 문제임.
-
작은 커밋의 대안으로, 큰 커밋을 되돌리지 않고 버그를 수정하는 새로운 커밋을 추가할 수 있음.
- 큰 리팩토링이 왜 나쁜지 명확하지 않음.
- 독립적인 구조를 만드는 것이 기존 모듈에 억지로 넣는 것보다 나음.
- API 설계 시, 유닛 테스트 대신 디자인 세션을 가질 수 있음.
-
테스트 가능성은 좋은 설계와 관련이 있음. 쉽게 테스트할 수 없는 것은 설계 변경이 필요하다는 신호일 수 있음.
- 테스트 코드는 다른 방식으로도 검토되어야 함.
-
프레임워크의 기능을 테스트할 때 주의해야 함. 프레임워크는 시간이 지나면서 변할 수 있음.
- 의존성을 업그레이드할 때 안전한지 확인하는 것이 테스트의 중요한 역할임.
-
커밋 크기에 대해, 특정 변경을 되돌려야 할 때를 대비해 쉽게 되돌릴 수 있는 커밋을 목표로 해야 함.
-
회사들은 안정적인 코드베이스를 원하지만, 지속적인 리팩토링이 필요함. 이는 안정성과 상충될 수 있음.