TIL 34일차 - node 심화주차 강의(2), LV3 개인과제 완료

박찬웅·2023년 3월 11일
0

항해99

목록 보기
39/105
post-thumbnail

23년 3월 11일

배운 것

오늘 심화주차에서 배운 것은 객체지향과 Layered Architecture Pattern에 대한 개념을 배우고, 추상화를 통해서 Layered Architecture Pattern 적용하는 방법을 배웠다. 그리고 그때 마지막 해결 못했던 LV3 개인과제를 마무리 하였다.

시도 한 것

5. 객체 지향

오늘 배운 내용들은 지금 당장으로는 개인과제 실습이나 이후 주특기 프로젝트, 클론코딩 프로젝트에서 반드시 써야하는 중요한 내용들은 아니지만 나중에 실무에서 필요한 개념이고 알아가면 좋은 개념들이였다. 보통 객체 지향이면 다른 백앤드 주특기인 JAVA Spring에선 중요한 개념이지만, 그래도 알면 좋은 내용들이였다. 먼저 객체지향의 개념을 살펴보면 강의노트에 따라서는 다음과 같이 정리 할 수 있다.

객체 지향은 소프트웨어의 핵심을 기능이 아닌 객체로 삼으며 “누가 어떠한 일을 할 것인가?”에 초점을 맞춥니다.

즉, 객체를 도출하고 각각의 역할을 정의하는 것에 초점을 맞춥니다.

  • 책임권한을 가진 객체들이 서로 메시지를 주고받으며 협력해서 필요한 기능을 수행하도록 시스템을 개발하는 것을 객체 지향이라고 합니다.
  • 크고 복잡한 시스템을 효과적으로 분해하고 구성할 수 있고, 손쉽게 이해하고 효율적으로 다룰 수 있게 도와주는 방법으로 인정받아 많은 프로그래밍 언어에 적용되어 왔고 지금은 가장 인기 있는 프로그래밍 패러다임으로 자리 잡습니다.

이런 객체 지향적인 것들은 다음과 같은 성질들이 있다.

  • 캡슐화 (Encapsulation)

    개념적이나 물리적으로 객체 내부의 세부적인 사항감추는 것캡슐화라고 부릅니다.

    즉, 캡슐화를 사용하는 가장 큰 이유는 정보은닉을 목적으로 합니다.

  • 상속 (Inheritance)

    상속이란 이미 정의된 상위 클래스의 특징을 하위 클래스에서 물려받아 코드의 중복을 제거하고 코드 재사용성을 증대시킵니다.

    즉, 하나의 클래스가 가진 특징(함수, 변수 및 데이터)을 다른 클래스가 그대로 물려 받는 것을 말합니다.

  • 추상화 (Abstraction)

    객체에서 공통된 부분을 모아 상위 개념으로 새롭게 선언하는 것을 추상화라고 합니다.

    즉, 불필요한 부분을 생략하고 객체 속성 중 공통적이고 중요한 것에만 중점을 두어 모델화 하는 것입니다.

  • 다형성 (Polymorphism)

    다형성이란 객체(클래스)연산을 수행하게 될 때 하나의 행위에 대해 각 객체가 가지고 있는 고유한 특성으로 다른 여러 형태로 재구성 되는 것을 말한다.

    즉, 동일한 메소드의 이름을 사용하지만 메소드에 대해 클래스마다 다르게 구현되는 개념이 다형성입니다.

  • 의존성 (Dependency)

    의존성이란 객체(모듈 및 클래스)들이 협력하는 과정 속에서 해당 객체들이 다른 객체를 의존하게 되는 정도를 나타냅니다.

  • 결합도 (Coupling)

    결합도는 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 의존성을 가지고 있는지를 나타냅니다. 결합도가 낮을 수록 좋다.

  • 응집도 (Cohesion)

    응집도는 모듈에 포함된 내부 요소들이 각각 연관되어 있는 관계의 정도를 나타냅니다. 응집도가 높을 수록 좋다.

다음은 프로그래밍 패러다임에 대해서 간략하게 정리하였다. 현재 자바스크립트도 기존의 자바에서 개선된 언어이기에 완벽한 객체지향은 아니여도 어느 정도 객체지향 프로그래밍이라고 볼 수 있다.

프로그래밍 패러다임에는 대표적으로 3가지가 존재합니다.

  1. 구조적 프로그래밍 (Structured Programming)
  2. 객체 지향 프로그래밍 (Object-Oriented Programming, OOP)
  3. 함수형 프로그래밍 (Functional Programming)

구조적 프로그래밍제어 흐름직접적인 전환에 대한 규칙을 제시합니다.

  • 구조적 프로그래밍기능을 중심적으로 개발을 진행합니다.
  • 구조적 프로그래밍은 프로그래밍이라는 기술이 시작되면서 가장 처음으로 적용된 패러다임입니다.

객체 지향 프로그래밍제어흐름간접적인 전환에 대한 규칙을 제시합니다.

  • 객체 지향 프로그래밍은 프로그램의 처리단위가 객체인 프로그래밍 방법입니다.
  • 객체 지향 프로그래밍은 “현실 세계를 모델링”하는 대표적인 프로그래밍 패러다임입니다.

함수형 프로그래밍할당문에 대한 규칙을 제시합니다.

  • 함수형 프로그래밍함수를 중심적으로 개발을 진행합니다.
  • 함수형 프로그래밍은 3가지의 패러다임 중 가장 처음 만들어졌지만 최근들어 겨우 도입되기 시작하는 패러다임 입니다.

마지막으로 객체지향의 설계 원칙의 5가지인 SOLID에 대해서 배웠다. 보통 설계 할 때 이러한 기준들이 있는데 객체지향에서 대표적인 설계 원칙이 있다. SOLID에 대한 개념도 다음과 같이 정리 하였다.

  • 단일 책임의 원칙 (Single Responsibility Principle, SRP)
    하나의 객체는 단 하나의 책임을 가져야 한다.
    즉, 클래스모듈변경할 이유단 하나 뿐이어야 한다는 원칙입니다.
  • 개방-폐쇄 원칙 (Open-Closed Principle, OCP)
    소프트웨어 엔티티 또는 개체(클래스, 모듈, 함수 등)는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
    • 즉, 소프트웨어 개체의 행위확장될 수 있어야 하지만, 개체를 변경해서는 안됩니다.
    • 조금 더 쉽게 설명하자면, 기존 코드에 영향을 주지않고 소프트웨어에 새로운 기능이나 구성 요소추가할 수 있어야 한다는 것입니다.
  • 리스코프 치환 원칙 (Liskov substitution principle, LSP)
    프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
    여기서 하위 타입이란 S 타입의 객체 o1, 각각에 대응하는 T 타입 객체 o2가 있고, T 타입을 이용해서 정의한 모든 프로그램 P에서 o2의 자리에 o1을 치환하더라도 P의 행위가 변하지 않는다면, ST의 하위 타입입니다.
    즉, ST의 하위 유형이면 해당 프로그램의 속성을 변경하지 않고 T 객체를 S 객체로 대체할 수 있습니다.
  • 인터페이스 분리 원칙 (Interface segregation principle, ISP)
    특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
    즉, 클라이언트가 필요하지 않는 기능을 가진 인터페이스에 의존해서는 안 되고, 최대한 인터페이스작게 유지해야합니다.
    조금 더 쉽게 설명하자면, 사용자가 필요하지 않은 것들에 의존하지 않도록, 인터페이스작게 유지해야 한다는 것입니다.
  • 의존성 역전 원칙 (Dependency Inversion Principle, DIP)
    프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다.
    , 높은 계층의 모듈(도메인)이 저수준의 모듈(하부구조)에 의존해서는 안된다.
    조금 더 자세하게 정리해보자면
    - 고수준 계층의 모듈(도메인)은 저수준 계층의 모듈(하부구조)에 의존해서는 안된다. 둘 다 추상화에 의존해야 한다.
    - 추상화는 세부 사항에 의존해서는 안 된다. 세부 사항은 추상화에 의존해야 한다.

6. Layered Architecture Pattern

이번 심화주차에 마지막 파트이며, 역시 반드시 적용해야 하는 건 아니지만 실무에서 알면 좋은 내용들이기에 아키텍쳐의 대한 개념을 살펴 보았고 그 중에서 가장 많이 쓰는 3-Layered Architecture Pattern 적용해보는 실습을 하였다.

먼저 아키텍쳐 패턴을 배우기 전에 도메인, 도메인 모델, 앤티티의 개념을 정리하였다.

  • 도메인(Domain)
    개발자 대부분은 비즈니스 프로세스를 개선하거나 자동화하기 위해 일한다. 도메인은 이런 프로세스가 지원하는 활동을 의미한다.

  • 도메인 모델(Domain Model)
    도메인 모델이란 유용한 특성을 포함하는 프로세스나 현상의 지도(Map)를 뜻합니다.
    도메인 모델은 비즈니스를 수행할 사람이 자신의 비즈니스에 대해 마음속에 가지고 있는 지도와 같습니다.
    도메인 모델링 (Domain Modeling)의 종류
    1. 엔티티 (Entity)
    2. 값 객체 (Value object)
    3. 도메인 서비스 (Domain service)

  • 엔티티(Entity)
    엔티티(Entity)는 실제 DB 테이블과 연관되어 있는 핵심 클래스이고, 엔티티를 기준으로 테이블이 생성되고 DB 스키마가 변경됩니다.

다음으로는 아키텍처 패턴에 대해서 개념을 정리하였다.

  • 아키텍처 패턴 (Architecture Pattern)
    아키텍처 패턴은 소프트웨어의 구조를 구성하기위한 가장 기본적인 토대를 제시합니다.

대표적인 아키텍처 패턴

  • 저장소 패턴 (Repository pattern)

    • 영속적인 저장소에 대한 추상화
  • 서비스 계층 패턴 (Service layer pattern)

    • 유스 케이스(Usecase)의 시작을 명확하게 정의하기 위한 패턴
  • 작업 단위 패턴 (Unit of work pattern)

    • 원자적 연산을 제공합니다.
  • 애그리게이트 패턴 (Aggregate pattern)

    • 데이터 정합성을 강화하기 위한 패턴
  • 아키텍처 패턴을 도입하기 전에 고민해야 할 것

    1. 아키텍처 패턴이 주는 이익비용에 대해 확실한 이유가 있어야합니다.
    2. 해당하는 아키텍처 패턴을 채택했을 때 어떤 장단점이 존재하는지 명확하게 인지해야 합니다.
    3. 여러 계층을 추가하기 위해 들이는 노력시간을 투자할 만한 가치가 있을 정도로 어플리케이션도메인복잡한 경우에만 아키텍처 패턴을 도입해야 합니다.

이제 이번 챕터에서 가장 핵심인 계층형 아키텍처 패턴 (Layered Architecture Pattern)에 대해서 설명하자면 다음과 같이 정리 할 수 있다.

  • 계층형 아키텍처 패턴(Layered Architecture Pattern)
    계층을 분리해서 관리하는 아키텍처 패턴이고, 현재 가장 흔하게 사용되고 있는 아키텍처 패턴 중 하나입니다. 단순하고 대중적이면서 비용도 적게 들어 모든 어플리케이션의 사실상 표준 아키텍처입니다. 어떤 아키텍처 패턴을 도입할지 확신이 없을 때에는 계층형 아키텍처 패턴은 좋은 선택지가 될 수 있습니다. 계층형 아키텍처 패턴은 어떤 경우든 계층을 분리해서 유지하고, 각 계층이 자신의 바로 아래 계층에만 의존하게 만드는 것이 목표입니다.

이렇게 계층형 아키텍처 패턴에도 보통은 3계층이지만 더 큰 프로젝트에서는 그 이상의 계층을 사용하게 된다. 그래서 가장 표준적이고 대중적으로 많이 사용하는 3계층 아키텍처(3-Layered Architecture)에 대해서 정리를 하였다.

3계층 아키텍처에서 구성되는 각각의 계층(Layer)는 아래와 같다.

  • 프레젠테이션 계층 (Presentation Layer)

  • 비즈니스 로직 계층 (Business Logic Layer)

  • 데이터 엑세스 계층 (Data Access Layer) | 영속 계층(Persistence Layer)

  • 3계층 아키텍처 (3-Layered Architecture)

    3-Layered Architecture는 아래의 3가지의 처리과정을 이용해서 구현합니다.

    1. Controller : 어플리케이션의 가장 바깥 부분, 요청/응답을 처리함.
      • 클라이언트의 요청을 처리 한 후 서버에서 처리된 결과반환해주는 역할을 합니다.
    2. Service : 어플리케이션의 중간 부분, 실제 중요한 작동이 많이 일어나는 부분
      • 아키텍처의 가장 핵심적인 비즈니스 로직이 수행되는 부분입니다.
    3. Repository : 어플리케이션의 가장 안쪽 부분, DB와 맞닿아 있음.
      • 실제 데이터베이스의 데이터를 사용하는 계층입니다.
  1. Controller
  • 클라이언트의 요청을 받음
  • 요청에 대한 처리는 서비스에게 전담
  • 클라이언트에게 응답
  1. Service

  • 사용자의 요구사항을 처리 ('비즈니스 로직') 하는 실세 중에 실세!!!
  • 현업에서는 서비스 코드가 계속 비대해짐
  • DB 정보가 필요할 때는 Repository 에게 요청
  1. Repository
  • DB 관리 (연결, 해제, 자원 관리)
  • DB CRUD 작업 처리

따라서 전체적으로 보면 다음과 같이 그림으로 표현 할 수 있다.

3-Layered Architecture에서는 아래의 플로우를 기반으로 로직이 수행됩니다.
1. 클라이언트(Client)요청(Request)을 보냅니다.
2. 요청(Request)을 URL에 알맞은 컨트롤러(Controller)가 수신 받습니다.
3. 컨트롤러(Controller)는 넘어온 요청처리하기 위해 서비스(Service)를 호출합니다.
4. 서비스(Service)는 필요한 데이터를 가져오기위해 저장소(Repository)에게 데이터를 요청합니다.
5. 서비스(Service)저장소(Repository)에서 가져온 데이터를 가공하여 컨트롤러(Controller)에게 데이터를 넘깁니다.
6. 컨트롤러(Controller)서비스(Service)결과물(Response)클라이언트(Client)에게 전달해줍니다.

이렇게 개념들을 정리 하고 기존에 사용하던 express로 3계층 아키텍처 패턴을 구현을 한번 해보는 연습을 하였다. 원래에는 api 작성하면 한 파일에다 다 적었는데 이렇게 각각 세개의 파일을 나누고 역할대로 나누게 되면 좀 더 상세하게 볼 수 있을 뿐 아니라 나중에 수정 할 때 연쇄적으로 수정 할 필요가 없어지게 된다.

7. LV3 개인과제 마무리

오늘 개념들을 정리하면서 중간에 기술매니저님이 오셔서 이틀전 32일차 TIL에서 보았겠지만 구현은 다 되었는데 다른사람이 쓴 게시글 마저도 수정 및 삭제가 가능해지는 치명적인 오류가 있었었다.

그래서 기술매니저님과 함께 코드를 분석해보면서 알게 되었는데 점점 코드를 분석해보니까 게시글 작성 할때도 2~3번째로 회원가입한 아이디로 로그인 한 다음에 게시글을 작성하면 첫번째 회원가입 한사람으로만 게시글이 등록되어 있었다는 것을 알게 되었다. 결국에는 로그인 미들웨어 파일에서 잘못되었던 것이였다.

const { userId } = jwt.verify(token, "customized-secret-key");
		// sequelize 사용할 때에는 where 절을 사용할 것
      const user = await Users.findOne({ where : {userId} }); 
      res.locals.user = user;
      next();

원래는 그냥 {userId}만 적었었다. 다만 저렇게 적는 것은 lv2때 배웠던 mongoose로 할때에는 맞는 코드였다. 다만 sequelize로 구현 할때는 저렇게 출력하면 안되었다. 바로 저렇게 where 절을 추가해야 비로소 정상적으로 코드가 작동이 되었다. 결국 저 한줄만 수정했으면 되었던 것이였다. 팀원들에게도 도움요청을 했었지만 결국 팀원들한테도 끝내 해결하지 못해서 오늘 기술매니저님이 와서야 해결되어서 상당히 허탈했었지만, 그래도 다음에는 이런 실수가 없기를 바라야겠다. 이렇게 LV3 개인 과제는 마무리 하였다.

해결

이번에객체 지향과 3계층 아키텍쳐의 개념을 배워서 블로그에 정리를 하였다. 그리고 며칠간 고생했던 LV3 개인과제를 성공적으로 마무리 하였다. LV3 개인 과제 깃허브 링크는 아래에 추가하였다. (다만 다음 주부터 구현 할 LV4 과제가 LV3 끝나고 계속 이어지는 며칠 뒤에 링크를 본다면 더 업데이트 되서 바뀔 수 있다.)
시퀄라이즈로 구현한 게시판 프로젝트

알게 된 점

오늘도 만만치 않았던 강의 내용들이였다. 실습보다는 이론 위주의 강의였는데 객체 지향 같은 경우에는 과거에 대학교때 잠깐 들었던 내용이였지만 상당히 오래전에 배운거라 다 까먹어서 다시 개념 정리하는데는 어려움이 있었다. 그래도 살짝 대학교때 배웠던 개념을 다시 생각해보면서 정리를 하였다. 시스템 아키텍쳐도 역시 쉽지 않은 개념들이였다. 대략적으로 어떻게 구조가 흘러가는지만 이해하는데 초점을 가지게 되었다. 사실 오늘 TIL에선 적진 않았지만, 강의노트에서 예시코드들으 보면서 이해하는게 좀 더 빨랐다. 그거 보면서 앞으로 복습을 해야 할 것 같은 느낌을 들었다.
그리고 마지막까지 나를 괴롭혔던 LV3 개인과제를 일요일 되기 전에 오늘 마무리 되어서 조금 늦었지만 성공적으로 구현을 마무리 하였다. 기존에 mongoose에서 Sequelize로 바꾸는 작업은 상당히 만만치 않았다고 생각한다. 이제 그래도 저번주는 이런 개념도 잘 몰랐는데 이제는 조금이라도 적응은 한 것 같다.

앞으로 할 일

내일은 일요일이라 푹 쉬고 주특기 NODE 숙련주차의 WIL를 작성 할것 같다. 그리고 월요일부터는 LV4 개인과제 하는데 목표를 둘 것 같다.

profile
향해 13기 node.js 백앤드

0개의 댓글