본문 바로가기
프로젝트

습관형성 앱 프로젝트 회고

by 초록구미 2023. 1. 1.

Github: https://github.com/WithPlanner

 

2022년 7월 초~8월 중순까지 참여했던 첫 팀프로젝트 경험을 회고한다.

첫 프로젝트였던 만큼 기술적인 내용뿐 아니라 개인적인 상황까지 조금 구구절절하게 써보려고 한다.

목차

1. 프로젝트 시작 전

2. 프로젝트 시작

   a. 프로젝트 주제

   b. 주요 기능

   c. 개발 인원 및 담당 역할

   d. 협업 과정

   e. 고민했던 부분들

3. 마무리

 

프로젝트 시작 전

본 프로젝트에 참여하기 전 나는 공대 2학년 1학기 과정을 듣고 있었는데, 이론은 열심히 공부했지만 개발 경험이 없으니 스스로가 속빈 강정처럼 느껴지던 때였다. 마침 교내 소프트웨어 개발 대회가 개최되던 시기였지만, 당시 나는 학부연구생으로서 딥러닝 공부에 매진하던 상황이어서 팀에 참여하는 것을 망설였다. 지망하는 분야는 웹 백엔드였지만 아직 아는 것이 없어 막연했고, 도움이 될 수 없을까봐 걱정도 많았다. 그런데 나중에 가서는 뭐라도 좋으니까 그냥 해보자는 마음이 더 강해졌다. 안되면 되게 만들자는 마음이었다. 결국 학기가 끝나고 개발을 시작한다는 프로젝트 팀에 지원을 했고, 팀원이 되었다.

기획 및 프론트엔드 디자인이 대략 완성된 상태에서 참여한 것이라 나는 기능개발에 집중하게 되었다. 기술스택도 이미 다 정해져 있었다. 나는 뭔가를 제안하기보다 1인분을 할 수 있도록 팀원들을 따라잡는 것을 목표로 삼았다.

 

프로젝트 시작

  • 프로젝트 주제

자발적으로 건강한 습관을 형성해 나가도록 도와주는 앱을 만든다. 사용자는 특정한 주제로 모임을 생성할 수 있고, 모임의 가입자들은 정해진 시간과 요일에 습관을 실천했음을 인증해야 한다(챌린저스를 떠올리면 쉬울 것 같다).

 

 
  • 주요 기능
    • 성신여대 구글 이메일 계정으로 인증 후 가입이 가능함(성신여대 학생 대상으로 개발되었음)
    • 간단한 설문조사를 기반으로 맞춤 습관모임 추천
    • 모임의 공개/비공개 여부를 설정할 수 있음. 비공개 모임에 가입하려면 비밀번호 필요
    • 습관인증은 게시물 인증(사진 첨부 가능)과 위치인증 두 가지 방식이 있음
    • 지도 API를 이용해 사용자 위치를 추적하는 위치인증을 통해 간단히 습관인증을 할 수 있음
      • 예를 들어 헬스장에 꾸준히 가는 것이 목표라면, 사전에 인증 장소로 헬스장을 지정하고 매번 인증할 때마다 위치인증을 하면 됨

  • 개발 인원 및 담당 역할

-프론트 1명(본인), 백엔드 및 서버 2명

Android studio에서 kotlin으로 프론트 기능 개발을 맡았다. 디자인만 존재하던 화면을 동작하게 만들고, retrofit2를 적용하여 팀원들이 만든 API를 적용했다.

프로젝트 시작 전 할 줄 아는 언어는 C++, 파이썬, 자바 조금이 전부였기 때문에 속성으로 kotlin 문법과 앱 프론트 개발을 공부했다(2주일 소요). 개인적으로 공부한 것을 정리할 때 에버노트를 활용했다. 

  • 협업 과정

1달 반의 기간 동안 매주 구글미트로 회의를 진행하여 진행사항을 보고하고 추후 개발 내용을 논의했다. 이때 프론트와 백엔드에서 각자 맡은 부분을 다른 파트의 팀원도 이해하고 피드백할 수 있도록 설명하려고 노력하였다.

좋은 팀원들을 만나 많은 것을 배웠다고 생각한다. 개인적으로는 질문을 어려워하는 성격이었는데, 기초적인 질문을 해도 잘 받아주고 친절하게 알려준 팀원들 덕분에 협업에 적응할 수 있었다. 효율적인 질답을 위해 공부할 수 있는 부분은 공부한 다음, 질문을 리스트업하여 보내는 습관을 만들었다.

또한 postman과 datagrip 등 DB와 api 관련된 툴의 기본적인 사용법을 팀원들에게 익혀 에러 발생 시 어느 단계에서 문제가 일어나는지 빠르게 파악할 수 있었다.

 

  • 고민했던 부분들

-가독성 좋은 깔끔한 코드 작성하기

백엔드를 맡은 팀원들도 프론트단에 코드를 작성할 일이 여러번 있었다. 다른 팀원이 내 코드를 봐도 이해할 수 있어야 했다. 이 문제를 개선하기 위해 다른 사람들의 깃허브에 들어가서 코드를 많이 읽어보기도 했다. 기능개발에서부터 허덕이다 보니 힘들긴 했지만, 적당히 참고가 됐다. 시간이 될 때 클린코딩에 대한 책을 읽고 정리하기로 마음먹었다.

 

-효율적인 코드 작성하기

효율적인 코드란 첫째로 메모리 낭비를 하지 않는 것이고 둘째는 적은 시간을 소요하는 코드일 것이다.

가장 고민을 많이 했던 경험을 예시로 들어보겠다.

아래 코드(더보기 버튼)는 메인화면에서 습관모임들을 리스팅해주는 함수인데, 커뮤니티 타입에 따라 다른 activity로 이동하기 위해 intent를 인수로 받아온다. 뒤로가기를 통해 이전 activity에 접근할 때도 화면 정보가 업데이트(새로고침)되도록 구현하고 싶어 onResume() 함수에 코드를 옮겼던 기억이 있다. 이렇게 하는 게 최선인지, 모든 화면을 매번 재실행시키는게 리소스 낭비는 아닌지 알고 싶어 조사를 많이 했지만 답을 얻지 못하고 이대로 진행했었다.

 

더보기
override fun onResume() {
        super.onResume()
        sharedPreference = getSharedPreferences("token", MODE_PRIVATE)

        // 클리어
        myRV_Items.clear()
        recommendRV_Items.clear()
        hotRV_Items.clear()
        newRV_Items.clear()

        // 리사이클러뷰 및 인텐트 정의
        val recRV = binding.recommendRecyclerView
        val myRV = binding.myRecyclerView
        val hotRV = binding.hotRecyclerView
        val newRV = binding.newRecyclerView
        val intent_join = Intent(this@MainActivity, CommunityJoinActivity::class.java)
        val intent_mainpost = Intent(this@MainActivity, CommunityMainPostActivity::class.java)
        val intent_mainLocPost =
            Intent(this@MainActivity, CommunityMainLocationActivity::class.java)

        // 커뮤니티 GET 해서 리스팅
        RetrofitService.communityService.mainListing(sharedPreference.getString("token", null).toString())
            ?.enqueue(object : Callback<MainList> {
                override fun onResponse(call: Call<MainList>, response: Response<MainList>) {
                    if (response.isSuccessful) {

                        var result: MainList? = response.body()

                        if (result?.isSuccess == true) {
                            var postList = result.result
                            viewCommunityList(recRV, recommendRV_Items, postList.recommendList, intent_join)     // 회원님을 위한 습관모임
                            viewCommunityList(myRV, myRV_Items, postList.myList, intent_mainpost, intent_mainLocPost)     // 회원님이 참여하는 습관모임
                            viewCommunityList(hotRV, hotRV_Items, postList.hotList, intent_join)     // 가장 활성화된 습관모임
                            viewCommunityList(newRV, newRV_Items, postList.newList, intent_join)     // 최신 습관모임

                            Log.d("최신 습관 모임", postList.newList.toString())

                            Log.d("MAIN", "onResponse 성공" + result?.message)
                        }
                    } else {
                        Log.d("MAIN", "onResponse 실패")
                    }
                }

                override fun onFailure(call: Call<MainList>, t: Throwable) {
                    Log.d("MAIN", "onFailure 에러: " + t.message.toString())
                }

            })
    }

 

이 글을 쓰는 시점에서 다시 생각하면, 답은 간단했다. 그냥 업데이트를 안 하면 된다. 여러 앱을 사용하며 관찰한 결과 뒤로가기할 때마다 새로고침을 해주는 앱은 별로 없더라. 굳이 원한다면 아래로 슬라이드했을 때 새로고침이 되는 기능을 구현할 걸 그랬다. 당시에 이 답을 내리지 못했던 이유는 구글링에만 집착하고 내 머리로 생각하지 않았기 때문이었다.

어떤 기능을 구현하고 싶을 땐 1) 그 기능이 꼭 필요한지, 2) 구현 방법에는 무엇이 있는지, 3) 각 방법의 효용성은 어떤지를 따져봐야 한다는 것을 알게 되었다.

 

-retrofit2와 JWT 토큰을 활용한 서버통신

나는 안드로이드와 서버가 어떻게 통신하는지 이해를 잘 못했다. 그래서 팀원들이 테스트겸 써준 코드를 보고 약간의 응용만 어떻게든 했다. 프로젝트가 끝난 뒤 컴퓨터 네트워크 강의를 듣고 원리에 대한 것을 이해할 수 있었다. CS 지식의 중요성을 통감하고, 더 열심히 공부해야겠다고 마음먹었다.

 

-해결하지 못했던 것

원래 지도 API를 통한 위치인증 구현은 내가 맡을 예정이었는데 시간이 부족해서 다른 팀원이 맡아서 해주었다. 내가 생각했던 방법은 GPS로 경도, 위도 정보를 받아오면 지도API 상에서 도로명주소로 변환하여 사전에 저장된 주소와 비교하는 것이었다.

이 방식엔 문제점이 있었다. 모든 경위도 정보가 주소와 대응되지 않는다는 것이었다. 게다가 GPS가 생각보다 정밀도가 떨어져 현재 위치를 잘 가져오지 못했다. 원인을 파악하는 데 시간이 많이 소모되어 완전히 해결하지는 못한 상태로 끝났었다. 처음부터 기능 설계를 잘했더라면 좋았겠지만, 그렇지 않더라도 다른 해결법을 재빠르게 모색하는 순발력이 중요한 것 같다. 또 이 문제에 대해 팀원들과 의견 공유를 더 했더라면 하는 아쉬움이 있다.

 

마무리

프로젝트 내내 내가 잘 하고 있는 걸까 걱정이 많았다. 그래서 더 열심히 하려고 했고 더 많이 하려고 했다. 대회가 끝나갈때쯤 팀원과 남은 작업을 하며 대화하는데, 이런 말을 들었다. 내가 처음인데도 만들어달라고 한 것을 다 만들어와서 놀랐다고 했다. 이 말을 듣고 굉장히 기뻤다. 도움이 되기 위해 무척 노력했었으니까.

팀원들에게 배운 게 정말 많다. 개발뿐 아니라 커뮤니케이션이나 협업 스킬도 보고 배웠다. 이번에는 내가 많이 배운 입장이었지만 다음에는 이 경험을 바탕으로 줄 수 있는 사람, 이끌 수 있는 사람이 된다면 좋겠다.

'프로젝트' 카테고리의 다른 글

자료구조 프로젝트 FIN  (0) 2022.12.04
자료구조 프로젝트 MID  (0) 2022.10.18

댓글