Django 디자인패턴

윤현묵·2023년 6월 30일
2

Django

목록 보기
17/17
post-thumbnail

현재 백엔드 소스에서 view단에서 모든 로직이 구현되어, 서비스 레이어 분리가 필요해 보임

django에서 사용되는 디자인 패턴에 대해서 조사

💡 비즈니스 로직(Business Logic)은 유저의 요청에 따른 결과물을 만들어내기 위한 일련의 작업들을 의미한다. 회원가입을 예로들면, 아이디 중복 체크를 할 때 유저에게는 단순하게 중복여부를 출력만 하지만, 내부적으로는 DB에 접근하여 유저가 입력한 아이디가 존재하는지 확인하는 절차가 진행된다. 다시 정리하자면, 사용자가 어떤 요청을 했을 때, 그 요청을 처리하기 위해 내부적으로 진행되는 절차를 비즈니스 로직이라고 한다.

View, Serializer

  • 일반적으로 사용. view, serializer에 비지니스 로직 넣음
  • serializer는 데이터 유효성 검증(validation)
  • 로직이 커질수록 view가 지저분해지고 직관적으로 파악하기 어려움
  • 복잡성이 높은 비즈니스 로직 추가를 피해야함
    • 특정 API에 기능이 종속되는 경우, 다른 API나, 배치잡에서 해당 기능을 재사용하기 어려움

Fat Model, Thin Controller

  • model에 기능을 모아두고, controller는 중계 역할로 구성
  • 코드 중복이 줄어들고, 객체지향적으로 코드 설계가 편하다
  • 서비스가 커지며 비즈니스 로직이 많아지고, 다양한 도메인이 섞이게 되면 복잡하고 관리가 어려움
  • 다른 model에서 상속을 하는 경우가 있다면 모든 비지니스 로직을 상속. 이런 경우 사이드 이슈 발생 가능성
  • 결국 프로젝트, 비즈니스 로직이 커지고 복잡해지게 되면 model을 분리해야 하는 레거시 코드가 될 수도 있음(한 app에서 많은 양의 코드가 있어서 복잡하기 때문에 유지보수 측면에서 좋지 않음)

Service layer

  • model과 view 사이에 비즈니스 로직을 담당하는 개념을 추가
  • service layer가 추가되면 모델에는 객체의 속성만 관리
  • 방식
    • Form / Serializer가 Service Layer를 대신
    • utils 모듈에 비즈니스 로직을 추가해서 사용
    • service 모듈에 비즈니스 로직을 추가해서 사용

++ 조회 / 응답 / 비즈니스로 분리하여 구성

  • 기존 Service Layer에는 비즈니스 로직의 수행 및 데이터 정합성 검증의 두 가지 역할
    Service Layer의 비즈니스 로직이 복잡해지면서 가독성을 떨어뜨리고, 개발자가 집중해야 할 비즈니스 로직을 파악하는 데 어려움
  • 이를 해결하기 위해 데이터를 검증하고 설정들을 관리하는 Python 라이브러리인 Pydantic을 사용한 Validator Layer를 추가하여 데이터 정합성 검증의 역할을 분리
  • Validator를 통해 데이터 검증을 완료한 후 Service 레이어를 호출하게 됨으로써 Service Layer는 비즈니스 로직의 수행에만 집중할 수 있게 되었습니다.
    • selectors.py
    • services.py
    • validators.py
    • veiws.py
  • 조회/응답/비즈니스 분리 예시
    • 쿼리 최적화가 필요하다면 Selector
    • 비즈니스 로직 파악이 필요하다면 Service
    • 응답 형태를 확인하고 싶다면 View를 확인하기만 하면 되는 구조
app_name
├── api
├── models.py
├── views.py
├── selectors
│	├── all_posts.py
│ 	├── user_posts.py
│	├── search_posts.py
│	└── ...
├── services.py
├── validators.py

queryset / manager

  • 모델에 쿼리를 호출하는 함수가 포함되어 있으면 대량 처리가 필요한 경우 최적화되지 않은 쿼리가 호출될 가능성이 높다.
  • 예를 들어, 여러 개의 포스트의 상태를 변경해야하는 경우, 로직이 모델에 종속되어있으면 포스트의 개수만큼 변경 쿼리가 호출
  • QuerySet을 사용하면, 한번의 update 쿼리로 여러개의 객체의 상태를 변경할 수 있다.
  • 따라서 QuerySet에 비즈니스 로직을 모아두면 Batch, Service Object에서 기능을 재사용하기 편하다.
  • 장점
    • 유닛 테스트가 쉬워진다.
    • 가독성이 높아진다.
    • 코드가 간결해진다.
    • 쿼리 최적화가 가능하다.

현재 구성

app_name(최근)
├── api
│	├── views.py
│	├── serializers.py
├── models.py
├── urls.py

app_name(이전, core)
├── 관련 tables(ex, courses)
│	├── urls.py
│	├── views.py
...
├── models.py
├── views.py
├── serializers.py

참고자료

비고

클린 아키텍처 / 헥사고날(이 부분은 아직 이해하지 못했으나, 추후 공부해보면 좋을 것 같아 추가했습니다.)

├── rentomatic
│ ├── app.py
│ ├── domain
│ │ ├── entities
│ │ │ └── room.py
│ │ ├── interfaces
│ │ │ └── repository.py
│ │ ├── request_objects
│ │ │ └── room_list_request_object.py
│ │ ├── response_objects
│ │ │ └── response_objects.py
│ │ └── use_cases
│ │ └── room_list_use_case.py
│ ├── repository
│ │ ├── memrepo.py
│ │ ├── mongorepo.py
│ │ ├── postgres_objects.py
│ │ └── postgresrepo.py
│ ├── rest
│ │ └── room.py
│ ├── serializers
│ │ └── room_json_serializer.py
│ └── settings.py
└── wsgi.py
profile
진정성 있는 개발자를 꿈꾼다

0개의 댓글