첫 팀 과제 회고

@Hiyen · January 17, 2024 · 12 min read

Preface

혼자 개발 공부를 하다 처음으로 팀으로 개발을 해보는 경험을 하게 되었다. 자바로 캠프 관리 커맨드라인 프로그램을 만드는 Tiny, Tiny 프로젝트였지만 이 과정에서 개발을 같이 한다는 것이 무엇인지 많은 것을 깨닫게 되어서 글로 기록하고 싶어졌다.

의견 모으기

팀원들도 협업으로 개발을 해본 경험이 없었기 때문에 리더인 나의 역할이 막중하다는 것을 느끼게 되었다. 어떻게 설계를 할지, 어떻게 구현할 기능을 나눌지, 그리고 그 코드들을 어떻게 합칠지 모두 백지상태에서 정해야 했다.

다행히도 우리 팀은 1주정도의 시간을 통해 모두 각자의 의견을 내고 그 의견에 대해 경청하고 고민하는 팀문화를 빌딩해왔었고 설계부터 제출까지 모든 과정을 같이 의견을 모으며 하나하나 해결해나갔다.

아래는 각 과정에서 우리 팀이 어떤 문제를 마주쳤고, 어떻게 해결해 나갔는지의 기록이다

설계

팀 과제를 하기 전 개인과제를 통해 설계에 대한 고민이 충분히 필요하다는 것이 팀의 공통의견이었고 설계를 어떻게 해야 할지에 대해 두가지 의견으로 나뉘어졌다.

  1. 다 같이 기능명세서를 작성하고 그를 바탕으로 설계도를 만들기
  2. 각자 4장의 기능명세서와 설계도를 작성한 후 합친다

토의 끝에 2번으로 결정했고 그 이유는 다음과 같다

  1. 각자가 기능명세서를 작성함으로써 팀원 모두 해결해야할 문제점에 대해 깊이 생각할 시간을 가질 수 있다.
  2. 4장의 설계도를 가지고 더 나은 설계를 고를 수 있다

문제점

이후, 각자 기능명세와 설계도를 합칠 때 문제점이 발생했다.

누군가는 MarkDown으로 기능명세를 작성하고 클래스 다이어그램을 그려오고, 누군가는 머릿속에서 정리하고, 클래스 다이어그램에 모든 것을 그린 사람도 있는 등 각자가 제각기의 방식으로 기능명세와 설계도를 완성했기에 이를 합치는데 많이 시간과 비용이 소요되었다.

정리하자면

  1. 기능명세, 설계도에 대한 공통의 마인드 모델이 없었고
  2. 각자를 만들어내는 툴이 일치하지 않았다.

해결

툴을 확정하고 기능명세와 설계도를 팀내에서 나름대로 정의를 내렸다.

선택된 툴
기능명세 : MarkDown
설계도 : Draw.io

정의
기능명세 : 조사, 수식여구등을 생략하고 구현해야할 모든 기능을 최대한 구체화한 글
설계도 : 클래스 명과 필드명으로 한 객체를 표현하고 연관관계만 선으로 표현한 다이어그램

으로 결정하여 해당 문제를 해결했다

구현

기능명세와 설계도를 완성한 후, 이 둘을 바탕으로 클래스 다이어그램에서 정한 클래스명, 필드명을 다 같이 몹 프로그래밍으로 구현했다.

이 후 구현할 기능을 각자의 희망대로 분배했고 다행히 희망사항이 겹치지 않아 각자 비슷한 분량의 기능을 구현하게 되었다.

내가 맡은 기능은 수강생 점수 등록 이었다.

문제점

구현 과정에서 많은 문제점이 발생했다.

개인적인 문제점은 내가 기능을 만들기 위해서는 미리 구현되어야할 수강생 등록을 다른 팀원이 구현 중이었기 때문에 팀원이 구현할 기능에 대해 짐작만 하고 코드를 작성할 수 밖에 없었다. 이는 결국 개인적으로 만족스럽지 못한 코드로 이어지게 되었다.

팀적인 문제점은 몹 프로그래밍으로 작성한 초기 코드를 각자 로컬로 받으면서 발생했는데,

  1. JDK 버전이 통일되지 않았고, .gitignore이 모두 달라 초기 환경설정에서 막히는 팀원들이 발생했다.
  2. git에 대한 이해도가 모두 달라서 프로젝트 진행이 불가한 팀원들이 발생했다.

해결

모든 해결 과정을 화면공유로 팀원 모두가 참여한 상태에서 함께 해결했다.

  1. JDK버전을 17로 통일했다.
  2. idea 폴더를 .gitignore에 포함시킨 후 브랜치를 다시 배포했다
  3. git 관련 아티클을 재공유했고 문제가 생긴 팀원의 화면을 같이 보며 git 명령어를 재숙지했다.

합치기

위 과정을 해결한 후 각자 동일한 환경설정으로 맡은 기능을 구현할 수 있게 되었다. 이후 시간을 정해 기능을 각자 완성하고 함께 모여 코드를 합치기로 하였다.

  1. main- dev-feature 로 브랜치를 나누었다
  2. main은 제출용 브랜치로 완성된 코드만 가지도록 하였다
  3. devfeature를 Pull Request로 Merge하였다

Merge는 몹 프로그래밍으로 모두 합의를 통해 진행했다

문제점

합치기 과정에서 가장 큰 문제가 발생했다

내가 처음으로 pull request 를 Merge하고, conflict를 해결하는 과정을 화면으로 공유했고 차례대로 다른 팀원들의 Pull Request를 Merge하는 과정에서 발생한 문제점이다.

  1. 각자 기능을 4분할로 나누고 하나의 Pull Request를 합치니 하나의 PR 코드양이 너무 많았다
  2. 깃 가이드라인을 팀내에서 문서화 하지 않아 합의했던 브랜치 전략을 놓친 팀원이 발생했다
  3. 코드 컨벤션을 팀내에서 문서화 하지 않아 서로의 코드를 이해하기 쉽지 않았다
  4. 1번과 3번이 겹쳐져 수많은 Conflict가 발생했고 이를 수습하는 식으로 Merge가 진행됐다

해결

합치기에서의 문제점이 너무 치명적이라 팀내에서 긴급하게 다음 방향을 토의했다. 처음부터 다시하기 혹은 지금 디버깅하며 코드를 조금씩 고쳐나가기, 두 가지 의견이 나왔고 제출일이 당장 다음날이라 디버깅하며 코드를 조금씩 고쳐나가기로 결정했다

나와 팀원 한분이 번갈아 드라이버를 잡고 몹프로그래밍으로 디버깅을 했고 해당 과정이 많이 어려웠다. 몇 백줄이 되는 익숙치 않은 변수, 메서드명, 코드 구조를 따라가야 했고, 테스트 코드도 작성하지 않았기 때문에 일일히 출력하고 Main을 돌려가며 디버깅을 진행했다.

다행히도 각자가 기능을 잘 완성해주어서 해결해야할 문제가 그리 크지는 않았다. 합치기를 마치고 이후 시간이 남을 정도였고, 추가 구현 기능은 합치기 과정에서 느낀 점을 토대로 페어프로그래밍으로 코드리뷰를 상세히 하여 Merge하였고 결과적으로 만족스러운 코드를 제출할 수 있게 되었다.

완성 레포지토리 https://github.com/jinkshower/CampManagement

첫 협업이 나에게 남긴 것

합치기해결하면서, 지금까지 왜 지켜야 하는지 와닿지 않았던 코드 컨벤션, 커밋 컨벤션, 깃 브랜치 전략 들을 문서화하고 팀원 모두가 지키는 것에 대한 필요성을 뼈저리게 느끼게 되었다.

또한 왜 모든 개발교육과정에서 소통공유를 강조하는지를 이해할 수 있었다. 우리 팀이 마지막에 그나마 만족스러운 결과를 낼 수 있었던 이유는 서로 의견을 가감없이 말하고 그에 대해 진중히 고민하고, 장단점을 살펴 대안을 고르는 팀 문화를 빌딩해왔기 때문이라고 생각한다

개인적으로는 나의 커뮤니케이션 방식을 되돌아보는 계기가 되었다. 나는 건의사항이 있으면 언제나 말해야 하고, 내가 생각할 때 불합리하거나 비효율적인 일은 언제나 토의를 통해 개선할 수 있다고 생각한다.

하지만 그러한 의견을 내면서 쿠션어를 사용하는 등 이른바 둥글게 말하기는 연습이 필요한 부분인 것 같다.

마지막으로 딱딱하게 글을 적었지만 혹시나 이 글을 볼지도 모르는 나의 첫 개발팀원분들에게 감사를 전한다.

@Hiyen
Always want to write sometimes