TIL[74].딕셔너리를 이용한 sorting (Code_refactoring)

jake.log·2020년 9월 29일
1

1차 프로젝트에서 ProductListView를 짜면서 가격순 정렬을 Restful API로 가져오는 코드를 짰었다.

1. Sorting은 if조건에 따라 되겠지?

당시 코드는 if 조건문을 사용하여 get으로 요청 받은 api가 일치 할 때 order_by로 정렬된 상품을 나열해주는 방식을 사용했다. 받아야할 api 주소가 달라지기 때문에 달라지는 조건(혹은 경우)에 따라 값을 전달해주면 된다고 생각을 했고, 아래와 같은 logic을 구현했다.

class ProductListView(View):
   def get(self,request):
        try: 
            sorted_products = request.GET.get('sort')
 
            if sorted_products == 'price_low_high':
                specified_products = Product.objects.order_by('product_price')
            
            elif sorted_products == 'price_high_low':
                specified_products = Product.objects.order_by('-product_price') 
            
            else:
                specified_products = Product.objects.all()  
            

            product_list = [
                {
                    'id'              : specified_product.id, 
                    'product_title'   : specified_product.product_title,
                    'product_details' : specified_product.product_details,
                    'product_price'   : specified_product.product_price, 
                    'thumbnail_url'   : specified_product.thumbnail_set.first().thumbnail_url            
                    }
            for specified_product in specified_products]
            
            return JsonResponse({"mice_list":product_list}, status = 200) 

        except ValueError:
           return JsonResponse({"message":'INVALID_LIST'}, status = 400)

그러나 이 코드의 문제점은 새로운 조건이 생겨날 때마다 sorting을 하여 if문이 계속 늘어난다는 점이었다. 해당 문제점을 위코드 멘토님께서 지적해주셔서 refactoring을 진행했다.

2. Sorting은 딕셔너리로 폭넓게 사용 될 수 있다.

sorting_condition = {'price_low_high':'product_price', 'price_high_low':'-product_price'} 처럼 딕셔너리를 선언할 경우 더 많은 조건이 생길때, if문 없이 딕셔너리에 키값만 추가해도 확장성이 증가한다는 조언을 통해 딕셔너리를 어떻게 구현할지 고민했다.

딕셔너리에 대해서 다시한번 공부하면서 키 값과 벨류 값을 적절하게 가져와 사용할 방법을 생각했다.
그래서 구현한 코드는 아래와 같다.

우선 sorting_condition을 딕셔너리로 선언해주고, for 반복문으로 키값을 가져온다.
키 값이 api에서 요청해주는 값과 같을 경우 키 값에 해당하는 벨류 값을 order_by로 정렬된 값을 반환한다.
기존 if 조건문을 사용할 때보다 코드는 더욱 간단해졌고, 확장성은 늘어났다.

앞으로 상품 리스트 필터 기능을 사용할 때 큰 도움이 될것 같고, 이번 리팩토링을 통해 잘 동작이 되는 코드도 다시 보고 새롭게 구현해보는 일이 얼마나 중요한지 느끼게 되었다.


class ProductListView(View):
   def get(self,request):
        try: 
            sorted_products = request.GET.get('sort') 
            specified_products = Product.objects.all()
            sorting_condition = {'price_low_high':'product_price', 'price_high_low':'-product_price'}
            
            for condition in sorting_condition.keys(): 
                if condition == sorted_products:
                    specified_products = Product.objects.order_by(sorting_condition.get(condition))

            product_list = [
                {
                    'id'              : specified_product.id, 
                    'product_title'   : specified_product.product_title,
                    'product_details' : specified_product.product_details,
                    'product_price'   : specified_product.product_price, 
                    'thumbnail_url'   : specified_product.thumbnail_set.first().thumbnail_url            
                    }
            for specified_product in specified_products]
            
            return JsonResponse({"mice_list":product_list}, status = 200) 

        except ValueError:
           return JsonResponse({"message":'INVALID_LIST'}, status = 400)
profile
꾸준히!

0개의 댓글