필독 온보딩 가이드 3장

GoldenDusk·2023년 8월 14일
0

독서

목록 보기
3/6
post-thumbnail

코드와 함께 춤을 - 레거시 코드에 임하는 자세

필독 개발자 온보딩 가이드을 읽고 정리하는 글이며, 혹시 문제가 되면 삭제하겠습니다.

🍋 들어가기 전에 레거시 코드란?

  • 유산, 산물이 된 코드
  • 게발 : 기술적인 부분 OS, 더 이상 쓰기 힘들거나 화나게 하는 코드
  1. 다른코드와의 개연성을 무시한 채 Due Date만 맞춰 작성한 코드
  2. 코드의 종속성, 디펜던스를 낮추려는 노력이 1도 없는 코드
  3. 코멘트 등을 전혀 남기지 않아 더 이상 수정, 보완이 어려운 코드
  4. 기능 단위의 함수 나아가 모듈 자체가 지나치게 큰 코드, 개발 코드는 의존성이 낮아야 한다.

1. 들어가기

코드베이스는 마치 아를르의 원형 경기장과 유사하다. 한 세대가 여러 계층을 작성하고 나중에는 또 바뀐다. 한 세대가 여러 계층을 작성하고 나중에는 또 바뀐다. 많은 사람이 코드에 손을 댄다. 테스트에 누락된 부분이 있더나 오래 전의 가설을 강제하는 테스트가 있을 수도 있다. 요구사항의 변화는 코드의 사용 방식과 얽혀 있다.

2. 소프트웨어 엔트로피는 늘어나게 마련이다.

🍋 소프트웨어 엔트로피

  • 코드가 지저분해지는 것을 뜻한다.
  • 개발자가 다른 사람이 쓴 코드를 이해못하거나 버그 수정등 다양한 이유로 생긴다.
  • 관리가 가능하다.

🍋 관리 방법

  • 코딩 스타일과 버그 탐지 도구는 코드를 깔끔하게 유지하는 데 도움을 준다.
    - 코드 리뷰 역시 지식을 전파하고 코드의 일관성이 떨어지는 것을 방지하는 데 도움이 된다.
  • 지속적인 리팩터링을 통해 엔트로피를 낮출 수도 있다.

3. 결코 피할 수 없는 기술 부채

🍋 기술 부채

  • 소프트웨어 엔트로피를 가중시키는 주요 요인
  • 기존 코드의 단점을 수정하면서 나중에 미뤄둔 작업을 말한다.
  • 차선책을 선택할 수록 구현하면서 점차 복잡도가 올라가며, 비용 또한 점점 늘어난다.
  • 레거시 코드는 수 많은 기술 부채가 산재해 있다.

🍋 기술 부채 매트릭스


1. 신중히 고민하다 의도적으로 만들어진 부채는 보편적으로 발생하는 기술 부채 유형이다. 나중에 팀이 해결 가능하도록 훈련된부채라면 이는 좋은 부채라고 할 수 있다.
2. 신중하지 못했지만 의도적으로 만들어진 부채는 주로 팀이 출시일 압박을 받는 상황에서 만들어진다. 보통 일단이라는 단어가들어 간다.
3. 신중하지도 의도치도 않는 부채는 않았던 부채는 알려지지 않은 미지, 몰라서 모르는 것들 때문에 발생한다. 꾸준한 학습과 코드 리뷰가 필요하다,
4. 신중했지만 의도치 않는 부채는 성장 과정에서 자연스럽게 나타나는 결과다. 단순히 누군가가 제대로 일을 하지 않아서생기는 것이 아니라 문제 도메인에 대해 배우는 과정이나 소프트웨어 아키텍트가 성장하는 과정 중 발생하는 자연스러운 결과다.

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

4. 기술 부채를 상환하는 방법

  • 문제를 해결할 수 있도록 한달동안 온세상이 멈춰주지는 않는다. 그러니 업무를 진행하면서 필요한 부분은 정리하고 조금씩 리팩터링을 하자. 변경사항은 작고 독립적인 커밋과 PR(풀 리퀘스트)로 만들자
  • 부채를 해결하면 출시 속도가 빨라지고 부채를 쌓아두면 출시 속도가 느려진다.

🍋 대규모 리팩터링

  • 만일 대규모 리팩터링이나 재작성을 제안하려 한다면 팀과먼저 의논해보자
    1. 상황을 사실 그대로 설명한다.
    2. 부채의 위험과 비용을 기술한다.
    3. 해결책을 제안한다.
    4. (부채를 그대로 두는 방법을 비록해) 대안에 대해 논의한다.
    5. 트레이드오프를 따져본다.

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

  1. 코드 변경은 새로운 리포지토리에 코드를 작성하는 것과는 다른 차원의 문제이다.
  2. 기존의 동작을 유지하면서 변경해야 하기 떄문이며, 다른 개발자의 사고 방식을 이해하고 기존 스타일과 패턴을 유지하는 것

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

처음 4개의 과정은 밭에 씨를 뿌리는 5번째 과정전에 주변을 정리하고 울타리를 치는 과정이라고 생각하자.

🍋 1) 변경 지점을 확인하자.

  • 밭에 씨를 뿌리는 은유에 빗대어 생각해보면 변경해야 할 지점이 바로 씨를 뿌리는 지점이다.

🍋 2) 테스트 할 지점을 확인하자

  • 수정하고자 하는 코드의 진입점, 즉 테스트가 직접 호출하고 값을 넣어보는 부분이다.
  • 테스트 지점은 변경 전에 현재 코드가 어떻게 동작하는지 보여주며 이 지점을 이용해 변경하는 코드 테스트

🍋 3) 의존성을 나눈다.

가장 위험한 과정으로 조금씩 작업을 진행하되, 새로운 기능을 추가하면 안됨, 테스는 자주 실행할 수 있도록 빨리 동작하게 만들자!

  • 테스트 지점을 찾기 위해 의존성을 나눌 필요가 있다.
  • 여기서 말하는 의존성 : 코드를 테스트하기 위해 필요한 객체나 메소드를 의미
  • 의존성을 나눈다 : 테스트가 용이하지 않은 코드의 구조를 바꾼다는 뜻

의존성을 나누는 방법

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

좀 더 쉽게 테스트 하기 위해 접근제어자 변경하지 말자

  • 캡슐화에 문제가 생김

🍋 4) 테스트를 작성

의존성을나누고 리팩터링을 하면서 기존 동작을 확인할 수 있는 새로운 테스트 추가

  • 자동 테스트 도구 사용 고려[6장에 자세히 나온다고 함]

🍋 5) 코드 변경

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

이름이 너무 긴 메소드, 클래스, 중복 코드, 너무 많은 분기나 루프, 너무 많은 매개변수 같은 문제를 찾아주는 린터(linter)나 코드 품질 도구가 많음

관련 링크 : 코드 품질 감사를 위한 9가지 최고의 도구
관련 링크 : linter

  1. 버그를 수정하거나 새로운 기능을 추가할 때는 주변 코드를 정리하자.
  2. 코드를 정리하는 커밋은 동작을 변경하는 커밋과 구분하자.
  3. 커밋의 크기가 작을수록 변경사항 리뷰에도 좋음

🍋 코드 악취

  • 버그는 아니지만 문제를 유발할 수 있는 패턴을 사용하는 코드
  • 이 코드 상에는 문제가 없으나
if(a<b)
	a+=1
  • 이렇게 코드를 짜면, 자바는 들여쓰기가 아닌 중괄호로 구문을 묶기 때문에 변수 a는 조건식과 무관한 2배의 값을 갖게 된다.
if(a<b)
	a += 1;
    a = a *2;
  • 여기서 생략된 중괄호가 바로 코드 악취

8. 점진적으로 변경하자.

  • 리팩터링 커밋은 작게 유지해야 한다.

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

  • 오래되거나 사용되지 않은 코드는 물론이거니와, 위험도가 낮거나 거의 호출되지 않는 코드는 리팩터링이 필요없다.

10. IDE를 활용하자.

🍋 가능하다면 도구의 장점을 활용하자.

  • IDE는 리팩터링을 할 때 특히 도움이 된다. 이름을 변경하거나 코드의 위치를 바꾸는 기능, 메소드와 필드를 추출하는 기능, 메소드 시그니처의 수정을 비롯한 다양한 보편적인 작업을 도와주는 여러 기능 내장

🍋 그렇다고 IDE가 변경한 코드를 그냥 지나쳐서는 안된다.

  1. IDE를 이용하면, 리팩터링이 너무 쉬워서 간단한 수정만으로도 엄청난 양의 코드를 변경할 수 있다.
  2. 반드시 사람이 리뷰
  3. 리플렉션이나 메타프로그래밍 형태로 참조하는 메소드의 이름을 바꾸면 관련 코드가 수정되지 않을 수 있다.

🍋 리플렉션(reflaction)이나 메타 프로그래밍(metaprogramming)이란?

리플랙션(reflaction)

  • 구체적인 클래스 타입을 알지 못하더라도 그 클래스들의 메서드, 타입 변수들에 접근할 수 있도록 해주는 자바 API
  • 리플렉션을 통해 클래스나, 메서드, 파라미터 정보를 가져온다.
  • 스프링의 어노테이션

메타 프로그래밍(metaprogramming)

  • 자기 자신 혹은 다른 컴퓨터 프로그램을 데이터 취급하며, 프로그램 작성 수정

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

변경한 코드는 깃과 깉은 버전 제어 시스템에 커밋해야 한다.

🍋 변경사항은 일찍 그리고 자주 커밋

  • 커밋을 자주하면 시간의 흐름에 따라 코드가 어떻게 변화해가는지 볼 수 있고, 변경을 되돌릴 수 있으며, 원격 백업으로도 활용 가능
  • 하지만 의미 없는 메세지들은 리뷰 요청 전 브랜치를 리베이스(rebase)하거나 커밋을 스퀴시(squash)해서 커밋 메시지를 명료하게 전달
  • 리베이스 : 깃에서 제공하는 인터그레이션 명령어
  • 스퀴시 : 커밋 히스토리 조정

🍋 커밋 스퀴시는 팀의 규칙에 따를 것

  • 보통은 [MYPROJ-123 백엔드에 포스트그레스 DB 도입] 커밋 메세지 앞에 이슈 ID를 붙힘

🍋 깃 COMMIT 메세지 작성 7가지 요령

그 외 참조[대문자 관련 내용 참조] : https://velog.io/@yeongmins/%EA%B9%83%ED%97%88%EB%B8%8CGitHub-%EC%A0%95%EB%A6%AC
1. 제목과 본문 사이에 빈 줄을 한 행 삽입한다,
2. 제목은 50자 이내로 제한한다.
3. 제목은 대문자로

feat : 새로운 기능 추가
fix : 버그 수정
docs : 문서 수정
style : 코드 스타일 변경 (코드 포매팅, 세미콜론 누락 등)
design : 사용자 UI 디자인 변경 (CSS 등)
test : 테스트 코드, 리팩토링 (Test Code)
refactor : 리팩토링 (Production Code)
build : 빌드 파일 수정
ci : CI 설정 파일 수정
perf : 성능 개선
chore : 자잘한 수정이나 빌드 업데이트
rename : 파일 혹은 폴더명을 수정만 한 경우
remove : 파일을 삭제만 한 경우

  1. 제목 끝에 마침표를 붙이지 않는다.
  2. 제목은 명령형 문장으로 작성한다.
  3. 본문은 각 행은 72자를 넘지 않게 한다.
  4. 본문에는 코드가 어떻게 바뀌었는지 보다는 무슨 코드가 왜 바뀌었는지 설명

12. 그 외

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

  • 코드를 처음부터 다시 작성하려 한다거나 표준을 무시하는 행동은 위험하다.
  • 개선한 코드는 기존 코드보다 몇 배 좋아야 한다.
  • 고부가가치를 낼 수 있는 상황에서만 재작성하자

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

  • 성공적인 기업이 오래된 라이브러리와 오래된 패턴으로 견고한 코드를 유지할 수 있는 데 이유가 있다.
  • 새로운 기술의 문제점은 성숙하지 못하다는 점이다.
  • 새로운 기술은 의외의 방법으로 문제를 유발한다.
  • 게다가 새로운 기술은 스택오버플로에서 관련 답변을 찾기도 어렵다.
  • 신기술이 회사의 경쟁력을 높여줄 수 있다면, 그 기술을 도입할 만한 가치가 있다.
  • 새로운 언어를 선택하는 것은 회사의 생태계에 기술 스택 전체를 때려 넣는것이다. 새로운 빌드 시스템, 테스트 프레임워크, IDE 라이브러리 등을 반드시 지원해야 한다.
  • 새로 선택하는 프로그래밍 언어의 생태계가 얼마나 성숙해져 있는지는 특히 중요한 사안이다.
  • 언어가 사장되지 않는 한, 단지 오래됐다거나 관심이 줄었다는 사실이 그 언어를 사용하지 않을 이유는 되지 못한다.

🍋 제발 악동은 되지말자.

단지 마음에 들지 않는다는 이유로 회사의 표준을 무시해서는 안된다. 표준을 바꿀 때는 우선순위, 소유권 비용, 구현, 세부내역 등 다각도로 고려해야 한다.

13. 개발자 필수 체크리스트

⭕ 이것만은 지키자❌ 이것만은 피하자
점진적으로 리팩터링하자기술 부채라는 단어를 남용하지 말자
리팩터링 커밋과 기능 관련 커밋은 분리하자테스트를 목적으로 메소드나 변수를 외부에 공개해서는 안된다.
변경사항을 작게 유지하자특정 언어에 연연하지 말자
처음 상태보다 코드를 더 깔끔하게 유지하자회사의표준과 도구를 무시해서는 안 된다.
평범한 기술을 사용하자업스트림 커밋없이 코드 베이스를 포크해서는 안 된다.

읽고 난 뒤

리팩터링도 이것저것 고려해야 한다는 점을 알았고, 그리고 특히 남을 설득할 때는 기간을 두고 신뢰감을 쌓고 얘기하자라는 생각이 들었다. 그리고 프로젝트때 여기 있는 것을 기반으로 커밋메세지 작성해봐야지

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. gitbook에도 정리중 ~

0개의 댓글