[JS]레이어드 패턴

hoifoi·2023년 12월 20일
1
post-thumbnail

들어가면서

앞서 배웠던 콜백함수에서 여러 코드들의 역할을 분업시켰다면
이번에는 조금 더 큰 덩어리에서 분업을 시킬려고 한다

클론 프로젝트를 할 때까지만 하더라도 작은 단위의 서비스였기 때문에
큰 필요성을 느끼지는 못했지만(클론도 일부 기능만 클론 한거라 더더욱..)
점점 복잡해져가는 코드를 보자하니 뭔가 교통정리가 필요함을 느꼈습니다
그리고 작은 서비스도 일련의 형식을 따랐을 때
아름다워진다는 것을 보았습니다..
(이과지만 멋진 그림을 그렸을 때 이런 느낌이지 않을까? 싶을정도..)

자 그럼 바로 해보겠습니다!

기존의 방식

아주 심플하면서도 간단해 보이는 모양입니다
하지만 server의 기능을 뜯어 보면 굉장히 복잡합니다

request를 받으면

  • URI와 메서드를 구별
  • 요청 데이터의 구성은 잘 갖췄는지 확인
  • 유저의 존재 유무 확인
  • 유저의 정보 확인 및 토큰 발행
  • 이후 데이터 베이스에 넣을 쿼리를 생성
  • 데이터베이스와 통신
  • 결과에 response를 송신

비유를 들어보기

이전에 제가 했던 영화관 아르바이트를 예로 들어볼께요!
오전조는 보통 2명을 씁니다(한적하다고 생각하기 때문)
하지만 공휴일이나 주말이라면?
생각보다 부지런한 사람들이 너무 많습니다..
정말 완벽한 체계가 잡혀있는게 아니면 엄청나게 우왕좌왕합니다..
팝콘 푸다가 매표소에서 소리치는 손님이 생기면 푸다가 가서 응대하고
팝콘을 퍼 놓으면 누가 그냥 들고갑니다(?) 그럼 그 주문은 끝났겠거니 했지만
내 팝콘 어디갔냐고 소리치는 사람이 생깁니다..(ㅜ)

확실한 파트를 나누지 않으면(근데 2명으로 나누기도 어렵습니다..)
언제 들어온 주문이 누구 손을 거쳐 누구를 통해 끝났는지 알기가 어려워
나중엔 문책도 하겠지만 당시엔 일처리도 잘 안되게 마련입니다..

제 코드는 작은서비스라 이게 될 줄 알았지만(놀랍게도 되버렸습니다.. 왜..?)
이후 프로젝트에서는 사이즈가 3배정도 커지다보니 감당이 되지 않았습니다..

그럼 섹션을 조금 나눠봅시다!

레이어드 패턴


위 그림과 같이 영역을 자세하게 쪼개 놓는 것입니다(완벽한 분업!)

앞선 비유를 여기서도 들어보자면
매표직원 따로, 매점 직원 따로, 청소 직원 따로, 입장관리 직원 따로..
이러면 각 단계에서 각자의 일만 하면되고,
각 단계에서 문제가 발생했을 시에는 이전단계로 다시 돌려보내면 해결이 됩니다!
예외도 있지만 보통은 표사고 팝콘 산뒤에 입장을 하는 패턴이기 때문이죠!

레이어드 패턴이란?

레이어드 패턴은 소프트웨어를 여러 계층(레이어)으로 나누어 구성해
코드의 기능별 독립과 유지보수성을 향상시키는 패턴입니다!

각 레이어별 설명

대표적으로 아래 세 개의 주요 레이어로 나뉘어집니다!

프레젠테이션 레이어 (Presentation Layer)

유저와 바로 통신이 닿는 레이어입니다
요청을 받아 해석하고, 비즈니스레이어로 부터 받은 결과를 응답하는 곳입니다
(이미지의 Routes, Controllers에 해당)

비즈니스 레이어 (Business Layer)

프레젠테이션 레이어로 부터 받은 데이터를 가공하고
비즈니스 로직을 수행합니다 이후 이 데이터를 기준으로
데이터 액세스 레이어를 호출하고 그 결과값을 다시 프레젠테이션 레이어로 보내줍니다
(이미지의 Services에 해당)

데이터 액세스 레이어 (Data Access Layer)

비즈니스 레이어에서 필요한 데이터를 받아
데이터베이스에서 필요한 정보를 받거나, 입력 및 수정을 합니다
외부 API와의 상호작용을 담당하기도 하며 데이터의 입출력을 처리하는 곳 입니다
(이미지의 Models에 해당)

각 레이어에서 하는 일에 대한 예시

각 레이어에서는 이전 레이어와 이후 레이어끼리만 상호 작용만 가능합니다
(첫번째 레이어와 세번째 레이어가 맞닿는 경우는 없다는 얘기)

이미지에서 보이는 각 단계를 기준으로 설명드리겠습니다!

Routes

Request를 받는 가장 첫 단입니다
Routes단에서 알맞은 URI와 메서드를 사용해 요청을 했는지 확인 합니다

  • 확인이 되었다면 - 이 내용을 담아 Controller단으로 전달합니다
  • 확인이 되지 않았다면 - 에러 내용을 담아 프론트에 Response를 전달합니다

Controller

Controller단에서는 Routes에서 받아온 데이터를 확인 합니다
(데이터를 최초로 확인 하는 단은 여기서부터입니다!)

  • 필요한 데이터가 없다면 error를 발생시키고 이 내용을 프론트에 전달합니다
    (예외처리나, 키값의 누락 등등이 여기서 에러를 발생시키게 됩니다)
  • 필요한 데이터가 있다면 비즈니스레이어에서 쓰기 좋게 데이터를 다듬어 전달합니다
    (스네이크 케이스를 카멜케이스로 바꾸거나, 배열을 객체로 바꾸거나 하는 등)
  • Service단에서 받은 데이터를 가공해 response에 담아 송신하는 단이기도 합니다

Service

1차로 정리된 데이터를 Controller단에서 받습니다

  • 필요한 데이터나 입력할 데이터가 있으면 models로 데이터를 요청합니다
    (게시글 조회를 원한다면 해당 내용을 조회, 입력했다면 해당 게시글을 입력하는 요청)
  • 알맞은 데이터가 없거나 일치한 데이터가 없을 시 error가 생기고 이 내용을 controller단으로 전달합니다

Models

Service단에서 요청하는 데이터 입력, 조회, 수정 등의 일을 합니다

  • 데이터 베이스와 통신에 필요한 쿼리를 생성합니다
  • 입력요청을 받았다면 입력 후 성공 메시지를 service단에 전달합니다
  • 데이터베이스와 통신 중 오류가 생기면 error가 생기고 이 내용을 service단에 전달합니다

회원가입 API를 통한 예시

계정 형식은 이메일형식의 ID와 12자 이상의 대소문자가 섞인 PW이고
필수 정보는 이름과 핸드폰 번호라고 가정해 볼께요!

  1. 유저가 입력한 데이터가 Route로 갑니다
    • URI나 메서드가 틀렸을 때 에러 발생
  2. Route 통과 성공 했으면 Controller로 갑니다
    • ID가 없으면 에러 발생(키 값 자체가 없거나 빈칸으로 들어온 상황)
      이후 이 내용을 프론트에 전달
    • PW가 없으면 에러 발생(키 값 자체가 없거나 빈칸으로 들어온 상황)
      이후 이 내용을 프론트에 전달
    • 이름이 없으면 에러 발생(키 값 자체가 없거나 빈칸으로 들어온 상황)
      이후 이 내용을 프론트에 전달
    • 핸드본 번호가 없으면 에러 발생(키 값 자체가 없거나 빈칸으로 들어온 상황)
      이후 이 내용을 프론트에 전달
    • 이후 데이터가 정제되어 Service로 전달
  3. Controller 통과 성공 했으면 Service로 갑니다
    • ID에 @가 없으면 에러 발생
      이후 이 내용을 Controller에 전달
    • ID에 .이 없으면 에러 발생
      이후 이 내용을 Controller에 전달
    • PW에 영문 대문자가 1개 이상 없으면 에러 발생
      이후 이 내용을 Controller에 전달
    • PW에 영문 소문자가 1개 이상 없으면 에러 발생
      이후 이 내용을 Controller에 전달
    • 핸드폰 번호의 형식이나 숫자가 11자 미만시 에러 발생
      이후 이 내용을 Controller에 전달
    • 비밀번호 암호화 후 Model로 전달
  4. Service 통과 성공 했으면 Model로 갑니다
    • INSERT INTO쿼리 생성 및 데이터베이스와 통신
    • 통신 중 데이터 입력에 실패 했으면 에러 발생
  5. Model의 작업이 성공 했으면 다시 Service - Controller로 돌아갑니다
    (에러 없이 Model단까지 데이터가 전달되었을 때 기준)
    그리고 마지막으로 Controller에서 프론트에서 성공메시지를 전달합니다

장점

독립화 및 유지보수성 향상

  • 각 레이어는 독립적으로 개발되고 테스트되므로 완전히 독립되며
    각 레이어의 변경이 다른 레이어에 미치는 영향이 최소화되는 장점이 있습니다
  • 예를 들면 로그인 기능을 쓸려고 하는데 토큰이 없다면 Controller에서 컷 당합니다.. service단은 접근도 불가능한 상황이 되어버리죠 때문에 불필요한 진행을 막을 수가 있어서 좋습니다
  • 또한 모든 에러는 각 단에서 발생하지만 수집은 controller단에서만 합니다
    에러를 다루기가 쉽고, 가독성이 좋아집니다!
    조금 의아하실수도 있는데 이부분은 에러 핸들링을 포스팅 하게 될 때 알려드리겠습니다!

테스트 용이성

  • 각 레이어는 독립적으로 테스트할 수 있어 전체 애플리케이션의 품질을 향상됩니다!

단점

각 레이어별 역할분담이 애매할 때

  • 역할을 확실히 나눠줘야 하기 때문에 확실한 이해가 필요합니다!
    (그렇지 못하면 팀원끼리도 다툴수도 있고, 충돌이 생길수가 있습니다)

오버엔지니어링 피하기

  • 작은 규모의 프로젝트에서는 간단한 패턴이 더 적절할 수 있습니다
    레이어드 패턴은 크고 복잡한 애플리케이션에서 특히 효과적입니다
    이 말인 즉슨, 진짜 작은 토이프로젝트라면 굳이 할 필요가 정말 없을 수 있습니다!
    (단체 프로젝트는 필연적으로 레이어드패턴이 도움이 되지만, 개인 프로젝트는 그냥 만들어도 무방한 경우가 많더라구요!)

적절한 사용

  • 모든 프로젝트에 레이어드 패턴이 항상 필요한 것은 아닙니다
    프로젝트의 규모와 복잡성에 따라 적절한 패턴을 선택해야 합니다
    다른 패턴도 많기 때문에 이부분 또한 저도 학습이 필요한 부분입니다
    대중적인 패턴이기도 하지만 서비스나 기능에 따라 다른 패턴이 더 최적화패턴일수도 있으니 무조건 귀막고 쓸 필요는 없다고 생각합니다 :D

마무리

자바스크립트 레이어드 패턴은
애플리케이션의 유지보수성을 향상시키고 코드를 구조화하는 데 도움을 줍니다!
각 레이어는 독립적으로 테스트 가능하며
역할을 명확히 구분하여 개발과 유지보수를 더욱 효율적으로 만들 수 있습니다!
그리고 제일 좋은건 프로젝트의 크기와 요구 사항에 따라
적절한 패턴을 선택하여 사용하는게 제일 좋은 것일겁니다!
(이참에 다른 패턴 공부도 조금 더 해봐야 할 것 같습니다)

++
발돋움 중인 예비 개발자 입니다.
태클 및 의견 공유 언제나 환영 :D

profile
컨텐츠 기획자 출신 백엔드 개발자 :D

0개의 댓글