Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3장 코드와 함께 춤을 #219

Closed
Tracked by #216
fkdl0048 opened this issue Feb 20, 2024 · 0 comments
Closed
Tracked by #216

3장 코드와 함께 춤을 #219

fkdl0048 opened this issue Feb 20, 2024 · 0 comments

Comments

@fkdl0048
Copy link
Owner

fkdl0048 commented Feb 20, 2024

3장 코드와 함께 춤을

레거시 코드에 임하는 우리의 자세

코드베이스는 한 세대가 여러 계층을 작성하고 지속적으로 변한다. 많은 사람이 코드에 손을 대고, 누락된 부분이 생기고 오래된 가설을 강제하는 테스트가 있을 수 있다. 요구사항의 변화는 코드의 사용 방식과 얽혀 있다. 그래서 코딩 작업이 어렵다.

소프트웨어 엔트로피는 늘어나기 마련이다

코드를 살피다 보면 단점을 발견하게 될 것이다. 여기저기 코드를 바꾸다 보면 지저분해지는 것은 자연스러운 일이다. 코드가 지저분하다고 개발자를 욕하지는 말자. 이렇게 코드가 지저분해지는 것을 소프트웨어 엔트로피라고 한다.

소프트웨어 엔트로피는 여러 이유로 생겨난다. 다른 사람의 코드를 이해하지 못하거나, 코등 스타일이 다르거나, 요구사항을 개선하다 보면 혼란이 생긴다. 이런 엔트로피를 개선하기 위해선 코딩 스타일, 디버거, 코드리뷰로 방지 가능하다.

코드 리뷰, 지속적인 리팩터링이 필요하다.

결코 피할 수 없는 기술 부채

기술 부채(technical debt)는 소프트웨어 엔트로피를 가중시키는 주요 요인이다. 기술 부채란 기존 코드의 단점을 수정하면서 나중으로 미뤄둔 작업을 말한다. 금융과 마찬가지로 원금과 이자가 있다. (원금은 수정해야할 원래 단점, 이자는 수정하지 않고 개선할 때 나오는 비용)

스스로 혼자 동의하지 않는 기술적 의사결정, 또는 별로 마음에 들지 않는 코드를 기술 부채라고 부를 수는 없다. 기술부채로 정의하려면 팀이 '이자를 지불해야 하는'것이거나 심각한 문제를 유발할 수 있는 위험 요인이어야 한다. (너무 남용 금지)

신중하지 못한 선택 신중한 선택
의도한 선택 "설계할 시간이 없어요" "일단 출시 후 결과를 보고 대처합시다."
의도하지 않은 선택 "계층화가 도대체 뭔가요?" "뭘 실수했는지 이젠 알겠네요."

신중히 고민하고 의도적으로 만들어진 부채는 보편적으로 발생하는 기술 부채 유형이다. 코드의 단점과 출시 속도 사이에서 고민하다 결정한 실용적인 트레이드오프인 것이다. 나중에라도 팀이 해결 가능하도록 훈련된 부채라면 이는 좋은 부채라 할 수 있다. (이런 확장성을 적절히 조절하는 것이 균형잡기이다.)

신중하지도 못하고 의도치도 않았던 부채는 알려지지 않은 미지(unknown unknowns), 즉 몰라서 모르는 것들 때문에 발생한다. (레빗홀) 이런 부채 유형은 사전에 구현 계획을 작성해 피드백을 받고 코드 리뷰를 수행하는 방법으로 완화할 수 있다.

건전한 팀은 회고 같은 절차를 활용해 의도치 않았던 부채를 찾아내고 부채의 해결 여부와 적절한 해결 시점을 논의한다.

기술 부채를 상환하는 방법

지속적인 리팩터링과 변경사항은 작고 독립적인 커밋과 PR로 만든다.

가끔은 대규모 리팩터링이 필요할 때가 있다. 소규모와 대규모 둘다 장단점이 존재하고(트레이드 오프가 존재하고) 균형잡기를 통해 결정해야 한다

코드 변경으로 인한 고통을 조금이라도 줄이려면

코드 변경은 새로운 리포지토리에 코드를 작성하는 것과는 다른 차원의 문제다. 기존의 동작을 유지하면서 변경해야 하기 때문이다. 다른 개발자의 사고 방식을 이해하고 기존 스타일과 패턴을 유지해야 한다. 또한 업무를 진행하면서 코드베이스를 서서히 개선해야 한다.

새로운 기능을 추가하던, 지우던, 리팩터링하던, 버그를 수정하던 대부분의 코드를 벽옇나느 기법은 비슷하고 이러한 기법을 혼합하여 사용한다.

레거시 코드 변경 알고리즘을 활용하자

  • 변경 지점을 확인한다.
  • 테스트할 지점을 확인한다.
  • 의존성을 나눈다.
  • 테스트를 작성한다.
  • 변경을 적용하고 리팩터링한다.

쉽게 정리하여 야생동물들이 날뛰지 않도록 울타리를 치고 코드를 리팩터링하는 것이다.

의존성을 나누는 방법은 다음과 같이 여러가지다.

  • 크고 복잡한 메소드는 더 작은 크기의 메소드로 나눠서 분리된 기능이 독립적으로 테스트될 수 있게 한다.
  • 인터페이스(또는 그 밖의 간접성)를 이용해서, 복잡한 객체를 완전하지 않아도 테스트하기에는 충분한 단순 구현체로 대체할 수 있는 방법을 마련한다.
  • 시간의 흐름같이 제어하기 어려운 실행 환경을 시뮬레이션할 수 있는 명시적 제어 지점을 주입한다.

리팩터링에 관한 내용이라 리팩터링 정리 링크로 첨부한다.

코드는 처음보다 더 깔끔하게 유지하자

"캠핑장을 떠날 때는 도착했을 때보다 깨끗하게 정리하라."

코드베이스도 공유 공간이므로 가능하면 깔끔한 상태로 유지하는 편이 좋다.

그래서 브랜치를 기능별, 리팩터링 등 목적에 맞게 작게 분리해야 병합할 때 최대한 깔끔하게 유지할 수 있다. 늘어남에 따라 힘들어지는 것 같다.

코드 냄새에 관한 내용으로 클린 코드 정리 링크

점진적으로 변경하자

리팩터링은 두 가지 유형을 띈다.

첫 번째는 수십 개의 파일을 한 번에 수정하는 모조리 바꿔 식의 변경이다. 두 번째는 리팩터링과 기능이 섞인 PR이다.

이 두 가지 변경은 리뷰하기가 훨씬 어렵기 때문에 최대한 리팩터링 커밋은 작게 유지해야 한다.

리팩터링은 실용적으로 진행하자

리팩터링이 항상 현명한 결정은 아니다. 마감일도 생각해야 하고, 우선순위도 고려해야 한다. 리팩터링에는 시간이 필요하다. 팀에서 출시를 위해 미루거나 기술 부채를 늘리지만 옳은 결정일 수 있다.

결국은 트레이드 오프다.

IDE를 활용하자

IDE는 특히 리팩터링 단계에서 도움이 많이 된다.

버전 제어 시스템의 권장 기법을 활용하자

작은 커밋과 메시지를 통한 명확한 의사전달, 백업등의 기능으로 코드 변경을 원할하게 유지할 수 있다.

실제 깃 커밋 메세지 작성 요령을 참고하거나 팀의 컨벤션을 따라가는 것이 좋다.

소프트웨어 개발에서 빠지기 쉬운 함정을 최대한 피하려면

기존 코드의 라이브러리, 프레임웤, 패턴등이 이미 많은 것이 담겨 있을 수 있다. 그 중에 마음에 들지 않아 더 깔끔하고 현대적인 방법으로 변경하고 싶지만 이런 행동은 매우 위험하다. (개인이라면 몰라도 회사라는 판매자 입장에서 위험하다.)

코드를 재작성하거나 규칙을 깨뜨리거나 또는 기술 스택에 새로운 기술을 추가할 때는 주의를 기울이자. 고부가가치를 낼 수 있는 상황에서만 코드를 재작성하자.

되도록 검증된 기술을 사용하자

당연하게 기술이 발전함에서 더 유용한, 편리한 기술이 등장할 수 있다. 하지만 오래된 패턴으로 견고한 코드를 유지함에는 그만한 이유가 있다. 성공을 거두는 데 시간이 걸리고, 기술을 갈아타는 것은 집중을 방해하는 요소가 되기 때문이다.

새로운 기술을 도입했을 때의 장점이 도입 비용보다 커야 한다. 회사가 비용과 장점 사이의 균형을 맞추려면 고부가가치 영역을 담당하고 광범위한 사용 사례에 적용 가능하며 여러 팀이 도입할 수 있는 기술에 투자해야 한다.

제발 악동은 되지 말자

단지 마음에 들지 않는다는 이유로 회사의 표준을 무시해서는 안 된다. 비표준 코드를 작성하는 것은 기업 환경에 맞지 않는 코드를 작성한다는 뜻이다.

더닝 크루거, 오만함으로 작성한 코드는 그에 따른 비용을 계속 뽑아내고 있다는 것이다.

가장 중요하게 생각하는 부분이다.

업스트림 커밋 없이 포크만 하는 것은 금물이다

당장 코드에 기여할 생각이 없으면서 해당 레포만 포크하는 것은 그다지 권장되지 않는다.

코드 재작성에 대한 욕구를 견디자

리팩터링을 하다 보면 기존 코드를 완전히 버리고 새로 작성하게 되는 경우가 있다. 종종 기존 코드를 버리고 모두 새로 작성하는 것이 좋을 것 같다는 생각을 하지만, 코드를 새로 작성하는 것은 최후의 수단이라고 생각해야 한다. (대부분 좋지 않은 선택이다.)

코드 재작성도 마찬가지로 그에 들어가는 비용보다 장점이 클 때만 시도해야 한다. 코드 재작성은 위험할 뿐더러 소요 비용도 높기 때문이다.

개발자의 필수 체크 리스트

이것만은 지키자 이것만은 피하자
점진적으로 리팩터링하자 기술 부채라는 단어를 남용하지 말자
리팩터링 커밋과 기능 관련 커밋은 분리하자 테스트를 목적으로 메소드나 변수를 외부에 공개해서는 안 된다
변경사항을 작게 유지하자 특정 언어에 연연하지 말자
처음 상태보다 작게 유지하자 회사의 표준과 도구를 무시해서는 안 된다
평범한 기술을 사용하자 업스트림 커밋 없이 포크만 하지 말자
@fkdl0048 fkdl0048 added this to Todo Feb 20, 2024
@fkdl0048 fkdl0048 added the 2024 label Feb 20, 2024
@fkdl0048 fkdl0048 self-assigned this Feb 20, 2024
@github-project-automation github-project-automation bot moved this to Todo in Todo Feb 20, 2024
@fkdl0048 fkdl0048 added this to the The Missing README milestone Feb 20, 2024
@fkdl0048 fkdl0048 moved this from Todo to In Progress in Todo Feb 20, 2024
@github-project-automation github-project-automation bot moved this from In Progress to Done in Todo Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

No branches or pull requests

1 participant