본문 바로가기
Always Awake/피로그래밍 12기(19.12.31~20.02.22)

로그쉐어 프로젝트 및 피로그래밍 12기 6주차 활동 정리(20.02.02~20.02.09)

by 욕심많은알파카 2020. 2. 12.

토요일(02.08)

협업에 대하여  by 황상현 선배님

 

-창업 Q&A

  • 초기 시작에 대하여 —>투자가 없어도 사업이 굴러는 가야한다.(투자가 반드시 필요하지는 않다), 창업 자체를 대단하게 생각하지는 말자.

-팀 소통

  • Git Hub 레퍼런스 —> 생활코딩 Git Hub강의, 구글링
  • Code It 외국강의. 퀄리티가 좋다.
  1. trello —> 무료 기간 길다.
  2. Slack —> 사내메신저. 개발자들이 쓰는 메신저. 개발과 연동 가능
  3. Jira —> 작은 규모의 사업에서는 소모적이지만, 대단위 조직에서 잘 사용되는 메신저. 이름/역할 정도만 알아둘 것. 개발과 연동 가능.
  4. Notion —> 강력한 템플릿, trello의 기능 다 가지고 있고…

-홈페이지 제작

  • 기획 --> 와이어 프레임으로 페이지에 대한 설명을 노션에 다 적어놓는다.
  1. Adobe XD
  2. Sketch
  3. PPT
  • 디자인
  1. Adobe XD —> 윈도우에서도 가능
  2. Sketch —> 맥에서만 가능
  3. Figma —> 뜨고있긴 한데 아직 기능이 조금 아쉽다.
  4. Zeplin —> 디자인 된 레이어를 코드로 바꿔주는 서비스
  • 개발
  • 런칭
  • 유지보수/하자보수

 

프로젝트 협업 가이드라인 및 코드 리뷰 by 김지현 선배님

 

프로젝트 협업

 

-DB Schema 설계

—> ER Diagram : 필요한 데이터 객체와 관계를 명확히 하여 오류를 발견하고, 수정할 수 있다. 

 

-Django Models 작성

—> OneToOne, ManyToMany를 안써도 되지만, 더 강력한 제약조건을 걸 수 있는 장고권장 스타일이기때문에..

 

-Skeleton Code 작성

—> 기획된 기능/ 기획서를 바탕으로 뼈대 코드를 작성 ( 어떤 기능인지 대한 코드)

—> URL Endpoint - 함수 맵핑 정의

—> 함수의 입력값, 리턴값/리다이렉션 어디로 갈지 정의

—> 한번에 기능을 정의하기 때문에 커뮤니케이션 비용을 줄인다. 개발할때 context switching이 적어짐. 정해진 기능을 개발하면 완벽한 동작의 코드가 만들어진다. 좀 더 발전하면, TDD가 가능하다.

 

-분업 후 협업 시작

 

-코드 리뷰의 목적

  • 가독성이 뛰어난 코드를 유지
  • 오류를 사전에 방지
  • 개인의 책임에서 조직의 책임으로
  • 타인의 코드로부터 배움

 

-대표적인 실수

    1. 맥락의 부재 —>어떤 용도로 사용되고 있는지 코드만 보고 추론할 수 있어야한다.
    2. 리턴 값의 추정 —> 함수가 리턴하는 값을 추정 할 수 있게 코드를 짜야한다. 이는 함수명을 잘 짜는 것으로도 가능.
    3. 추론 가능한 변수명 —> 해당 변수명이 어떤 타입인지, 무엇을 담고 있는지 변수명만 보고도 알 수 있게 짜야한다.
    4. 하드코딩(If-else의 남발) 피하기 —> 새로운 sector 분기점이 생겼을 때 로직 자체를 건드려야 하고, 코드가 불필요하게 길어지기때문에 유지하기가 어렵다.

코드를 짤 때 정적인 코드와 동적인 코드를 분리하는 것이 좋다.

정적인 코드 : 로직파트, 만들어놓으면 다시 추가/수정할 일이 별로 없는 코드

동적인 코드 : 컨텐츠파트, 다시 추가/수정할 것이 예상되는 코드

 

 

팀프로젝트 1주차

팀프로젝트 명 : Log Share

서비스 목표 : 자신의 활동을 기록(log)하고 같은 그룹의 사람들과 서로의 활동을 공유, 검색(share)하는 것을 돕는 웹사이트

 

태어나서 처음 하는 서비스 개발 및 기획이었어서, 처음 겪어보는 과정들이 참 많았다.

화/목/토의 정기 모임을 제외하고도 우리팀은 월, 수, 금 세번을 더 만났는데, 일주일동안 스켈레톤 코드를 짜고 기본적인 기능을 구현하는 것만 해도 굉장한 시간을 잡아먹었다.

 

특히 중점적으로 느꼈던 것은 5명이서 하는 팀프로젝트이고, 모두의 의견을 반영하여 하나의 서비스를 만드는 것이다 보니 커뮤니케이션과 Git에 사용되는 시간이 정말 많다는 것이었다. merge하기 전 컨플릭트를 해결하는 데에만 몇시간을 쏟곤 했다. 따라서 개발시간과 회의 및 소통시간을 따로 잡을 필요성을 조금 느꼈다.

 

우리 팀이 일주일동안 프로젝트를 진행했던 과정은 이랬다.

 

월 : 서비스 기획 및 모델짜기

화 : 모델 짠 것 바탕으로 회원/그룹/프로필/포스팅/검색 브랜치를 각각 따고, 기능 최소 구현.

수 : 각 기능의 부족한 점 고치고, 팀원들끼리 첫 번째 코드 공유

목 : 연관성 있는 브랜치끼리 합치고 구동 확인 / 코드 다듬기.

금 : 5개의 브랜치를 모두 merge하여 정상적으로 동작하는 지 확인하고, 완결과제 및 새로운 이슈들 정리하여 깃에 올리기.

토 : 선배님에게 코드리뷰 받고, 앞으로의 기술적/기획적 방향 정하기.

 

코드리뷰가 1주차 토요일에 바로 있기 때문에, 최대한 많은 코드를 짜가고 기술적 질문을 준비해가려고 노력했다.

 

첫 서비스 기획을 하면서, 간단히 프레젠테이션 받았을 때와는 달리 5명이 생각하고 있는 서비스의 모습이 각기 다르다는 것을 알게 되었다. 서비스의 목표는 무엇인지, 어떤 가치가 있으며 기존의 서비스들과는 어떤 차별성이 있는지를 하루 종일 고민했다.

 

서비스 기획의 흔적 1
서비스 기획의 흔적 2

나는 공학입문설계 등의 수업을 듣지 않았기 때문에 이러한 프로젝트 기획과정이 어떤 방식으로 이루어지는지 전혀 몰랐다. 다행히도 팀원들이 팀프로젝트 경험과 관련 수업을 들었던 경험이 있어서 그 방식을 많이 배워가면서 서비스의 틀을 잡을 수 있었다.

 

flow chart 1 by 성익
flow chart 2 by 성익

내가 맡은 파트는 포스팅파트와, 포스팅에 딸린 태그를 구현하는 일이었다. 태그를 통한 검색도 로그쉐어의 핵심파트 중 하나였기 때문에, 검색파트를 맡은 팀원과 함께 코드를 공유해가며 작업했다. 

 

포스팅 앱 자체는 이전에 배웠던 CRUD를 이용하여 구현할 수 있는 기본적인 기능이었다.

내가 맡은 파트에 관한 기술적 문제들은 이랬다.

 

1. Taggit 모듈의 사용

 

최초에 짰던 모델 중에는 Post에 딸린 Tag모델이 따로 있었다.

해당 태그는 Post를 FK로 참조하면서 내부에는 word라는 CharField를 가진 간단한 모델이었는데, 구현이 가능함에도 해당 모델을 최종적으로 사용하지 않았다.

 

이유는 다음과 같다.

- 이미 django에서 태그를 구현해놓은 모듈이 충분히 많다.

- Taggit 모듈을 사용하면 여러 개의 태그를 구별할 문자열 split등의 과정을 생략할 수 있다.

- Taggit 모듈을 사용하면 대소문자의 무시나 slug 지원 등의 몇가지 유용한 기능이 있다.

 

따라서 이미 만들어진 모듈을 가져다 사용하는 것이 낫다고 판단하여 Post에 TaggableManager를 이용해 태그를 추가하였다.

 

처음에는 태그의 분리가 굉장히 간편하고, 여러 태그를 넣기에 간편하다는 생각이 들어 좋았다. 그러나 태그를 이용한 기능들을 계속 설계하다보니, 내가 직접 설계한 모델이나 필드가 아니었기 때문에 정확한 구조를 몰라 제대로 사용을 하지 못하는 경우가 있었다.

 

아래의 Post모델을 보면 tags는 특정 필드나 테이블이 아니라, TaggableManager라는 클래스의 객체로 설정되어있다. 이 때문에 정확히 tags가 어떤 속성을 가지고 있는지, 내부에 어떤 테이블이 어떤 구조로 엮여있는지에 대한 이해도가 부족했다.해당 클래스가 있는 파일로 들어가 선언된 속성과 함수들을 보아도, 간단할 줄 알았던 구조가 굉장히 많고 복잡하게 되어있어서 제대로 이해가 되지 않았다.

 

문제의 TaggableManager

이런 문제점들을 마주하고 나서 mysql에서 EER Diagram을 열어 어떤 테이블이 만들어졌는지 눈으로 보고 이해하려고 노력했다. post에 딸린 tags를 불러오는 쿼리셋의 SQL문을 직접 콘솔 로그로 찍어 어느 테이블과 어느 테이블을 어떤 방식으로 Join하려는지 확인했다.

 

이런 과정들을 거쳐 태그를 불러오거나 분리하는 과정을 비교적 능숙하게 다룰 수 있게 되었다. 이를 통해 느낀 점은, 아무리 좋은 모듈과 기술을 가져다 쓴다고 하더라도 동작 원리와 구성에 대한 이해가 없으면 안쓰느니만 못하다는 것이었다. 태그 기능이 중요하긴 해도 애초부터 조금 더 정교하게 직접 설계한 태그모델을 사용했으면 차라리 시간이 덜 들었을 것 같다는 느낌도 들었다. 물론, 익숙해지고 난 뒤부터는 그런 생각이 조금은 없어졌다.

 

 

2. 해시태그를 이용한 검색

 

Taggit모듈을 이용하여 태그 자체를 구현한 뒤에는 태그를 검색하여 해당 태그를 가진 포스팅을 검색할 수 있도록 하는 해시태그 검색기능을 추가했다. 이미 팀원 중 한명이 검색 파트를 구현하고 있었으므로, URL에서 쿼리를 받아 해당 쿼리에 대응되는 검색페이지로 이동하는 방법을 찾아보려 했다.

 

이 과정에서 URL로 넘어온 request의 parameter를 넘겨받는 방법을 공부할 수 있었다. 또, 해당 태그를 가진 포스트를 필터링하여 결과물을 리스트화시키는 법도 배웠다.

 

그런데 문제는 검색기능 자체가 아니라, 찾아본 레퍼런스에 있었다. (레퍼런스가 잘못되었다는 뜻은 아니다)

 

 

[Project] 해쉬태크 검색

해쉬태그 검색을 하고 싶다면? url에 있는 해쉬태그는 콘솔에서 볼 수 있었다. 근데 문제는 http://127.0.0.1:8000/images/search/?hashtags=cheap,hot 이렇게 입력했을 때, cheap와 hot가 한 개의 단어처럼 출력..

supplementary.tistory.com

django에서 해시태그 검색을 구현한 블로그 레퍼런스는 많았는데, Taggit 모듈을 이용한 대부분의 레퍼런스가 APIView를 사용하고 있었다. APIView는 REST API에서 지원하는 기능이었는데, 이 과정에서 코드를 이해하기 위해 REST API에 대해 이해하고 넘어갈 필요성을 느꼈다.

 

 

3. REST API

 

위의 이유로 DRF(Django Rest Framework)의 공식문서를 찾아보며 기본 세팅을 하고, 개념을 잡으려 노력했는데, 결과적으로 닭잡는 데에 소잡는 칼을 쓴 격이 되고 말았다.

 

REST API를 사용하는 이유는 백엔드와 프론트엔드의 완전한 분리를 위해서이다. 이게 무슨말이냐 하면, Django와 같은 풀스택 프레임워크에서 template(MVC 패턴에서의 view)은 view(MVC 패턴에서의 controller)에서 넘겨주는 context안의 정보만 이용할 수 있다.

 

엔드유저에게 직접적으로 정보를 보여주는 서비스의 얼굴, template부분은 정보의 시각적 구성을 위해 필요한 정보들을 특정하고 이를 가져오는 로직을 view에서 짜서 context로 넘겨야 한다. 이 과정에서 백엔드에서는 템플릿에 보내야 하는 정보와 로직을 계속 고민해야하고, 프론트엔드에서는 그 정보를 어떤 방식으로 표시할 지를 고민해야한다.

 

이는 자칫 백엔드와 프론트엔드를 반복해서 오가는 비효율적인 동선 낭비가 될 수 있다. 또, 로직에만 집중하거나(백) 시각화에만 집중(프론트)할 수 없어 제대로 된 분업을 할 수 없게 된다. 그렇다면, 백엔드는 프론트엔드에서 요청한 정보를 가져와 넘겨줄 로직만 짜고, 프론트엔드는 받은 정보를 시각화하는데에만 집중할 수 없을까?

 

이 과정을 쉽게 해주는 것이 REST API이다. DRF에서는 serializer라는 강력한 도구를 이용하여 DB 정보를 Json형식으로 제공한다(또는 입력으로 제공받은 정보를 DB에 넣어준다). Serializer에서 명시해 둔 대로 정보를 가져오기 때문에, 백엔드는 이를 통해 DB에서 원하는 정보를 가져와 그대로 context에 넘기기만 하면 프론트엔드에서는 백엔드가 어떻게 돌아가는지 알 필요 없이 해당 정보를 편하게 사용할 수 있다.

 

그러나 나는 이런 이해가 없는 상태로 단순히 serializer를 사용하는 레퍼런스를 참고했기 때문에 API View를 제대로 사용하지 못했다. 원하는 정보를 보여주려면 이를 구성하고 시각화 할 APIView를 직접 짜야하는데, REST API는 너무 추상화된 도구이기 때문에 이를 공부하는데에 너무 오랜 시간이 걸릴 것이라고 선배님이 말씀하셨다. 또, 이미 CRUD의 대부분을 구현한 지금 REST API를 통해 다시 뷰를 짜는것은 시간낭비일 뿐이었다(REST API를 사용하면 Viewset을 이용해 CRUD 기능을 훨씬 짧은 코드로 구현할 수 있다).

 

결국, 쿼리문을 받는 방법정도만 배운 뒤 프로젝트에서는 REST API를 사용하지 않기로 결심했다. 우리팀에서는 백엔드와 프론트엔드를 나누어 개발하고 있는게 아니라, 각각 본인이 맡은 파트의 백과 프론트를 모두 만들고 해당 코드를 지속적으로 공유하여 전체적으로 조율하는 방식을 채택하고 있어서였다.

 

그러나 Rest Framework라는 개념에 대해서 조금 더 이해할 수 있었고, DRF가 제공하는 강력한 기능들과 편리함에 대해서 알게 되었기 때문에 반대로 프로젝트가 끝난 후 DRF를 공부해보고 싶다는 생각이 들었다.

 

팀원 중 한명의 강아지 뚜기. 너무 귀여워서 보면서 힐링하고 있다.

 

프로젝트를 1주간 하면서 참 조바심을 많이 느꼈다. 배운것만으로는 마음에 드는 서비스를 만들기에 생각보다 충분하지 않았다. 내가 더 기여하지 않아도 팀원들은 자기 파트를 잘 구현해 냈다. 다른 팀들에 비해 기술적으로 다양한 시도를 해보고, 대단한 결과물을 내고 싶었다. 그래서 더 어려운 기술이나 유용해보이는 것들에 집착했던 것 같다.

 

1주간의 팀플을 하고 코드리뷰를 받고 나서는 조금 생각이 고쳐졌다. 지금의 나는 서비스를 완성하기 위해서 개발을 하고 있다. 내가 새로운 기술을 사용해 서비스의 완성도를 높일 수 있다면 분명 좋긴 할것이다. 그러나 무엇보다 중요한 것은 서비스가 제대로 동작하고, 충분한 가치를 생성하는지이다. 이를 위해서는 UX를 개선하기 위한 기술적 시도가 필요한 것이지, 남들보다 더 어려운 프레임워크와 라이브러리의 사용이 중요한 것이 아니다. 팀으로서의 결과물을 만드는 데에 집중하는것, 기본에 집중하는것이 가장 중요한 것 같다. 프로젝트도 처음 해보는 주제에 너무 오만하고 성급하게 생각을 했었다.

 

따라서 내가 좀 더 잘 할수 있는 부분에 집중하기로 했다. 팀원들에게 기여하기 위해 현재 이슈를 정리하고 필요한 레퍼런스를 체크한 뒤, 프로토타입을 만들어 제공하는 포지션으로 가려고 한다. 이 과정에서 기획에도 최대한 많이 참여하는 것이 좋은 것 같다. 정말 한주 한주마다 부족함을 느끼고, 반성하게 되는 요즘이다.

댓글