4주 프로젝트-dev log #14

Joshua Song / 송성현·2020년 2월 27일
0

im_16 프로젝트

목록 보기
18/21

Introduction

어느정도 진행을 하고 서버 코드를 뒤돌아보니, 너무 route 부분에 코드들이 집중이 되어 있어 역할별로 코드를 정리하고 분리해 가독성을 높으고, 또 역할에 맞게 코드를 정리해야겠다고 결정이 나 더 늦기전 리팩토링을 하겠다 결심했다.

MVC Pattern

N-Queens 를 할때 살짝 설명하고, 중간중간 과제에 적용된 것으로 보이는 MVC 패턴은 어떻게 소프트웨어를 개발할 것인지의 디자인 패턴 중 하나로, 특히 사용자와 상호작용을 하는 애플리케이션을 개발할 때 흔히 사용된다.
M(Model): 비지니스 영역의 로직을 처리한다.
뷰(View): 비지니스 영역에 대한 시야, 화면을 담당한다.
컨드롤러(Controller): 사용자의 입력과 흐름을 담당한다.

여기서 비지니스 로직이란 데이터를 생성, 표시, 저장, 변경하는 부분, 즉 데이터를 처리하는 일련의 과정들을 비지니스 로직이라고 한다.
같이 프로젝트를 봐주시는 개발자 분과 상의를 통해 API가 그렇게 많지 않고 시간도 진짜 없는 경우이기에 그냥 route 부분과 controller부분을 합치기로 했고 (추후에 시간이 남으면 가독성과 역할 정리를 위해 나눌 생각도 하고 있다 (해결함!) ) 라우트 안의 비지니스 로직 부분을 DAO와 서비스로 나눠주기로 했다.

DAO & Service

  • DAO란 Data Access Object의 약자로 Data에 접근을 위한 객체이다. DAO가 있는 이유는 데이터베이스에 접근을 하기 위한 로직을 분리시켜줘 데이터베이스 액세스를 DAO안에서만 해 다수의 DB 호출문제를 해결할 수 있다. 먼저 라우트에서 요청을 받아 무슨 컨트롤러인지에 따라 필요한 서비스를 찾아 작업을 시킨다. 그러면 이 서비스들에서 DAO에 요청을 해 데이터베이스의 직접적으로 접근해 복합적인 CRUD를 해결하고, DAO에서 넘겨주는, 디비에서 가져온 결과값들을 서비스에서 가져와 컨트롤러 / route 가공을 한 후 뷰를 담당하는 클라이언트에 넘겨준다. 컨트롤러에서 데이터를 가공하는 반복적인 함수들은 라이브러리로 따로 빼서 import해와서 사용해주었다. DAO는 쿼리빌더로 데이터베이스에 접근해 하는 CRUD만, service는 들어오는 요청에 필요한 기능들을 구분해 놓는 코드, controller는 요청들어온 데이터를 기본적인 가공만 해 필요한 service로 처리하고 클라이언트에 넘겨주는 코드, 그리고 route는 들어오는 요청을 바로 적절한 컨트롤러에 넘겨준다.

확실히 이러한 리팩토링을 통해서 코드의 역할을 나누고 가독성 면에서 훨씬 향상된 점을 볼 수 있었다. 시간이 많이 걸리긴 했지만 MVC 패턴을 적용해서 코드를 정리했다는 점이 보람찼다.

Active Record vs Data Mapper?

  • TypeORM을 처음 적용할 때 단순히 엔티티를 만들고 쿼리빌더와 타입스크립트를 적용해서 정신없이 서버코드를 짜느라 빨리 캐치하지 못한 감이 있지만 TypeORM에는 Active Record와 Data Mapper 라는 패턴을 적용할 수 있다.
  • 두 패턴은 TypeORM에서 데이터를 처리하는데 도움이 되라고, 사용자가 더 편리하라고 있는 패턴으로, 처음 코드를 작성할때는 두 패턴 다 적용하지 않은, 그냥 평범한 MVC 패턴만 적용해서 DAO에는 쿼리빌더를 일반 함수처럼 정의해서 사용하기만 했다. 일단 두 패턴을 비교해서 장단점을 비교해보고 싶었다.

What are they?

TypeORM 공식홈페이지

  • Active Record 패턴으로 접근한다면 모든 쿼리 메소드들과 필요한 CRUD를 엔티티 안에 정의할 수 있다. 엑티브 레코즈 패턴을 사용하면 모델안에서 데이터 베이스 접근이 가능하다는 장점이 있다. 사용방법은 공식 홈페이지를 참조하면 된다. CRUD를 하는 쿼리빌더를 엔티티 안에 컬럼과 같이 생성한다고 생각하면 된다.

  • Data Mapper 패턴으로 접근한다면 레포지터리 라는 별도의 클래스를 만들어 모든 쿼리 메소드를 정의해준다. 이 레포지토리를 사용해 CRUD사용하기 때문에 엔티티는 칼럼과 관계만을 정의하는 제한적인 역할만을 수행한다. 그래서 데이터베이스에 연결해 접근하는 부분은 다 레포지토리에서 처리한다. 커스텀 레포지터리를 만들어서 사용하면 된다.

일단 큰 차이점은 애플리캐이션을 유지하는데 차이가 있다. 데이터 매퍼 접근법을 사용하면 유지보수에 더 효과적이여서 큰 애플리케이션이고 더 많은 데이터를 다룬다면 더 유리하다. 따로 기능과 데이터베이스를 분리해관리하기에 설계적인 측면에서도 더욱 효과적이고 더 유연하다. 액티브 레코즈 접근법은 아무래도 한 엔티티 안에 다 정의하기 때문에 더욱 간단하고 작은 애플리케이션에 있어 더 효과적이다. 유지보수도 더 쉬울 수 밖에 없다.

결국 도메인 로직이 복잡하다면 Data Mapper를, 아니라면 Active Record를 사용하면 된다.

우리 프로젝트 같은 경우는 일단 로직이 매우 길고 다양하기 때문에, 그리고 장기적으로 봤을 때 많은 데이터가 저장되어 처리해야 하기 때문에 Data Mapper를 도입해서 사용하는게 더욱 좋을 것이라 생각했다.

Data Mapper 적용

이런식으로 캣태그라는 EntityRepository를 만들어 준 후 CatTag 레포지토리를 연결해주어서 이 안에 필요한 CRUD들을 만들어 준다. 이렇게 클래스를 만들어 준 후 export를 해준다면 서비스에서 필요한 DAO를 선정해 사용한다.

const catTagRepository = () => getCustomRepository(CatTagRepository);

그리고 서비스 파일에서는 만들어놓은 repository를 가져와야 하기 때문에 (DB와 연결) 위 코드를 실행해줘야 레포지토리에 있는 메소드들을 사용할 수 있다.

데이터 매퍼를 사용하면 체감상 못 느끼겠지만 설계면에서 더욱 유리하고 유지보수에 도움이 된다는 장점이 있기에 패턴을 도입했고 성공적으로 코드가 잘 실행된다는 점이 매우 만족스럽다.

마무으리

  • 일단 서버 코드 기능 부분을 어느정도 완수해서 이런 효율을 따지고 구조를 따질 수 있는 시간과 기회가 생겨 매우 다행이라고 생각한다. 백엔드를 맡았기에 기능을 떠나서 더 좋은 구조와 효율을 따지는 게 행운인 것 같다. 이제 배포로...가즈아

참고 - 생활코딩

profile
Grow Joshua, Grow!

0개의 댓글