위 말처럼 우스갯소리로 하는 말이지만, 내가 밟아온 과정들을 다시 소중히 정리하지 않는다면 온전히 내 것으로 만들지 못할 것만 같다.
내가 심여를 기울여 작성한 코드들, 그리고 그런 코드들을 더 알맞고 효율적인 형태로 가꾸는 방법을 나에게 알려주기 위해 노력한 여러 사람들의 가르침을 헛되이 하고싶지 않기에 내가 경험한 배움의 과정들을 이 곳에 남겨보려한다.
학습 목적으로 제작한 '오설록' 사이트 클론 프로젝트
커머스 사이트의 가장 기본적인 기능 구현
Front-End : 이윤섭(PM)님, 손가영님, 김현주님, 안수정님
Back-End : 황재승, 최바다님
커머스 웹사이트의 가장 기본적이고 필수적인 기능을 완성하기
프론트엔드의 개발 속도에 맞추어 완벽히 데이터를 전달할 수 있도록 진행상황 관리하기
가독성이 높은 코드 작성하기
연산처리 속도에 신경써서 코드 작성하기
어려운 부분을 마주하면 팀원과 소통하여 함께 헤쳐나가기
과한 욕심으로 프로젝트 전체 계획에 차질 주지 않기
모델링을 할 때, 가장 기준이 되는 테이블을 PRODUCT
로 선정하고 차례차례 그림을 그려나갔다. 특히, 중복 카테고리를 가지고 있는 제품들이 있어 관계를 설정하는 데 있어서 많은 고민을 했다.
(ORDER
와 관련된 테이블은 모델링 단계에서 미리 구상하였지만, 추가 기능구현 사항으로 일단 배제해두었다.)
클론 코딩을 진행할 사이트의 핵심 기능들에 대한 간단한 초기 데이터를 google spreadsheet을 사용해서 구상하였고, 이를 토대로 scv 파일을 따로 작성하여 MySQL WORKBENCH를 통해 DB에 저장하였다.
함께 프로젝트 진행하신 바다님께서 맡아주신 부분!
Annotate
를 통한 필터 기능 구현prefetch_related()
를 통한 연산처리 개선::: 하나의 Method를 통해 DB에 액세스하는 횟수를 줄여주어 Performance를 크게 향상시킴
< BEFORE >
class CategoryView(View):
def get(self, reqeust):
menus = Menu.objects.all()
< AFTER >
class CategoryView(View):
def get(self, reqeust):
menus = Menu.objects.all().prefetch_related('maincategory_set', 'maincategory_set__category_set')
q = Q(
if menu:
q &= Q(categoryproduct__category__main_category__menu__id = menu
if main_category:
q &= Q(categoryproduct__category__main_category__id = main_category
if category:
q &= Q(categoryproduct__category__id = category
if search:
q &= Q(name__icontains = search
sort_type = {
'reviews' : '-total_reviews',
'sales' : '-total_sales',
'new' : '-id',
'price_desc': '-price',
'price_asc' : 'price'
products = Product.objects.filter(q).annotate(total_sales=Sum('orderitem__quantity', distinct=True))\
.annotate(total_reviews=Count('review__id', distinct=True))\
.order_by(sort_type.get(sort))[offset:offset+limit]
filter_set = {
'main_category' : 'categoryproduct__category__main_category__id',
'menu' : 'categoryproduct__category__main_category__menu__id',
'category' : 'categoryproduct__category__id'
}
filter = {filter_set[key] : value for key, value in request.GET.items()}
products = Product.objects.filter(**filter).annotate(total_sales=Sum('orderitem__quantity', distinct=True))\
.annotate(total_reviews=Count('review__id', distinct=True))\
.order_by(sort_type.get(sort))[offset:offset+limit]
FE & BE 소통 및 팀의 분위기
개개인 팀원 모두의 명확한 의사소통과 매일 진행되는 Stand-Up Meeting에서의 각자의 진행상황 공유를 통해서 요청/전달 사항들에 대해서 명확히 할 수 있었다.
코드 리뷰
오랜 시간동안 고민하고 작성한 코드에 대해서 멘토님께서 명확히 리뷰를 해주셔서 너무 감사했다.
나 또한 정확한 피드백을 받기위해서 PR을 올릴 때마다 "지금 이 코드를 작성한 이유" 및 "작성 과정에서 갖게된 의문점"에 대해서 항상 명확히 설명하도록 노력했고, 멘토님께서는 이 부분에 대해서 내가 정확히 이해할 수 있도록 항상 짚고 넘어가주셨다.
지금 생각하면 1차 프로젝트를 진행하는 과정에 있어서 코드를 리뷰받는 그 시간이 가장 재밌고 유익했던 것 같다.
시간 분배 실패
계획했던 필수 기능 구현은 성공적으로 마쳤다.
하지만, 애초에 내가 계획한 것은 ORDER
에 대한 부분까지 시간 내에 구현하는 것이었고, 안일한 시간분배로 인해서 결국은 실패하고 말았다. 조금 더 빠듯하게 시간을 분배해서 진행했다면 충분히 추가기능까지 구현 가능했었을 것이다.
API 명세서
모델링 과정부터 프론트엔드 분들과 조금 더 의논하고, 각자 구현하시는 페이지에 필요한 데이터들에 대해서 좀 더 많이 이야기할 수 있는 시간을 갖지 못한 부분이 아쉬움으로 남았다.
또한, 그 시간의 부재로 인하여 그리고 나의 무지로 인하여 API Documentation 없이 프로젝트를 계속 진행하였고, 결국 통신하는 과정에서 프론트엔드에서 필요한 데이터를 놓쳐 부랴부랴 추가해서 전달해야했던 치명적인 실수까지 하고 말았다.
위코드에 와서 시간을 보낸 1달 반가량의 기간동안 내가 어렵게 선택한 이 길이 나에게 진짜 맞는 길인지, 위코드에서의 기간이 끝나면 정말로 내가 한 명의 개발자로써 현업에서 일할 수 있을지 계속 고민해왔다.
서로 화이팅 하며 응원해주는 팀원 덕분에 1차 프로젝트를 진행하는 동안은 그런 고민을 단 한번도 하지 않게 되었고(고민할 시간도 없었지만...), 처음으로 함께 맞춰가는 개발이 재밌다고 느꼈다.
그리고, "함께 성장하는 개발자" 가 되고 싶다 생각했다.
분명히 프로젝트를 만족스럽게 마무리할 수 있었던 것은 분명 팀원 모두가 배려하고 노력했기 때문임으로 잘 알고 있다.
나 또한 함께 끌어가고 끌어줄 수 있는 개발자가 되보고자 노력한다.
좋은 글 잘 읽고 갑니다~