프론트엔드 데브코스 5기 TIL 19 - 노션클로닝(4). 디자인패턴 변천사

김영현·2023년 10월 23일
1

TIL

목록 보기
22/129

서론

노션 과제를 한창 진행할때였다.
강의를 보며 생각없이 코드를 따라쳤다. 그리고 수정했다.
=> 똥같은 결과물이 나왔다.

사실 그럭저럭 봐줄만했다. 하지만 어딘가 부족했다.
구조를 정확히 설명할 수 없고, 상태관리도 부실해보였다.
특히 인스턴스에 대한 개념이 아주 무지한채 사용했더니, 코드가 이상했다.
자세히는 모르지만 이상했다.
=> 메타인지를 했다.

어딘가 방법이 없을까 하며 고민했다. 마침 이번 과제는 생성자 함수를 이용하여 하고있었다.
이건 결국 객체지향이 아닌가?
그러면 디자인 패턴을 찾아보면 되겠구나!
마침 상태관리옵저버 패턴으로 리덕스처럼 구현해보려 했다.
그래서 디자인 패턴의 역사, 특히 프론트 엔드쪽에서의 역사에 대해 알아보았다.

당장은 이것만 필요하잖아?


아키텍처란?

https://www.youtube.com/watch?v=4E1BHTvhB7Y
결정은 변경하기 어렵다

처음부터 올바른 방법으로 설계해서 코드를 짠다.
이것이 핵심이다.
단기적으로 똥같은 코드가 빨리 만들어진다.
But, 시간이 흐를수록 기능추가-수정 등, 코드를 건드릴 일이 생기면 자연스레 좋은 코드가 더 빨리 해결가능.


디자인 패턴

출처는 테오님의 블로그입니다!
https://velog.io/@teo/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%97%90%EC%84%9C-MV-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94

좋은 아키텍처란, 결국 어떻게 잘 분류하냐?의 문제다.
그 방법이 디자인 패턴 인거고.

MVC

초창기에는 소프트웨어를 Model, View, Controller로 나누는게 좋다고 봤다.

  • Model: Db
  • View: 화면
  • Controller: 로직 처리

간단하게 설명하면 이렇다. 우리 프론트엔드로 대입해보자면
Model => 서버, 서버api, db
View => html, css
controlloer => Model의 데이터를 받아와 View를 보여주는 처리(js)

초창기에는 백엔드에서 화면을 제작(controller)하여 뿌려주었기에
사실상 백엔드만 디자인 패턴을 알고있다 봐도 무방했다.

이후 Ajax기술이 추가되며, jquery를 이용한 Dom조작(Controller)이 활발하게 이루어지며
Restful Api로 받아온 데이터가 Model이 되었다.

MVVM

그런데, 귀찮음이 증가했다.
수많은 동적 노드작업이 발생하여 DOM조작관련 코드가 너무 많아지게되었고
특히 백엔드에서는 템플릿을 이용하여 선언적으로작업하였으나, 프론트엔드에선 일일히 수정해야 하였다.

이래선 안되겠군! 하고 나온것이
Model View ViewModel
DOM 조작등은 일체 라이브러리-프레임워크에게 맡기고 View를 그리는 Model만 맡게 되었다!

  • 기존의 간접접근 (id,class 등)에서 직접 접근(노드 자체)로 바뀌었다!

presenter - container

이건 리액트 배울때 잠깐 훑어본 패턴이다
컴포넌트재사용 가능해야한다. 이는 새로운 개념이 아니라, 객체지향에서 계속 말하던 부분이다.
어떻게 보면클래스 인거지?
아무튼, 이 재사용 가능한 컴포넌트를 만들기 위해선비즈니스로직을 최대한 겉어내야한다.
따라서 비즈니스 로직이 들어갈 공간이 자연스레 필요해졌고
container라는 부모컴포넌트를 만들어, 여기서 비즈니스 로직을 처리한다.
presenter컴포넌트는 데이터를 뿌려주기만 하면 되고든요!

flux

흠. 위의 방법도 괜찮았지만, 컴포넌트의 깊이가 깊어지면, props drilling이 발생하게된다.
쉽게말해, 부모의 상태머나먼 자손까지 일일히 다 전달해야한다.
해봤으면 알테지...굉장히 귀찮고, 상태가 필요없는 자식도 상태를 가져야한다
또한, 필요 없는 리-렌더링도 일어난다.
이는 재사용 가능한 컴포넌트를 만들기위하여 파편화된 Model들 때문이다
=> 결국, MVC를 기반으로 한MVVM에서 재사용 가능한 컴포넌트를 만들다 일어난 일

하지만, 재사용 가능한 컴포넌트는 포기할수 없다. 얘는 착한눔이여
그렇다면, 데이터의 흐름을 단방향으로 만들면 되지 않을까?

그래서 등장한것이...

redux

리덕스는 센세이션을 일으켰다!

  1. View가 어떠한 Action을 취하면
  2. Dispatcher를 통하여 Reducer에 들어가 뚝딱거린다
  3. 전역 Store를 통하여 상태를 구독하고 있는 컴포넌트에게 뿌려준다.

Action => Dispatch(reducer) => Store => View
이러면 비즈니스 로직을 작성할땐 reducer에 작성하면 되겠구나?
=> 리액트를 겉핥기식으로 다루며 redux를 사용했을땐 비즈니스 로직이 여기저기 혼재했다.

하지만...한계도 분명있다.

  • 높은 학습 곡선
  • 보일러 플레이트

특히 보일러 플레이트는 말할 것 없다.
이를 보완하기 위하여 Redux-ToolKit이라는 라이브러리도 나오긴 했음

Observer Pattern

다른 방법으로 Props drilling을 풀어보자는 의견도 있었다.
장황한 Action, dispatch등을 제거하고
상태를 구독한 구독자들에게 변화가 생기면 무조건 알려준다

앵귤러에서 채용했던 패턴이기도 하다.

현대 프론트엔드 아키텍처 방향성들

중요하지만 지금 당장은 중요해보이진 않는다...다음편에 다루도록 하겠음!


결론

왜 공부했냐?
=> 코드가 장황하고 통일성이 없었음. 특히 클래스 내부 메소드가 진국이었음.

얻은게 뭐냐?
=> 객체지향을 더 잘 이해하게되고, 특히 재사용 가능한 컴포넌트를 잘 알게됨. 상태 의존성을 최대한 제거해야함!
또한 옵저버 패턴은 결국 pub-sub패턴이라는 것을 알게되었고 클래스 메소드를 잘 정리하게 됨.
데이터의 흐름 파악도 쉬워짐.
그리고 이번 과제를 통해 계속 고민하던 것들이 사실은 디자인 패턴 변화 흐름대로 깨우치고 있었다는걸 알게됨
Dom조작 => 생성자 함수를 이용한 컴포넌트화(with historyapi, spa) => 내가 만들 전역 스토어
역시 선조의 지혜구나...

그래서 어떻게 할건가?
=> 다음 과제부터는 디자인 패턴을 잘 적용해보려함. 귀찮더라도 지켜야할건 지켜야함.
그리고 이번 과제에서 제작할 전역 스토어(구독,알림 방식)을 보다 잘 만들어보겠음.


번외) 문자열에 스프레드 연산자를 사용하면?

    if (name === "class") {
      [...value].forEach((className) => {
        $button.classList.add(className);
      });
    }

혹시 될까 싶어 사용해봤는데, 된다.
대신 abcd[a,b,c,d]로 잘린다.
유사배열객체라서, 한 글자가 한 인덱스니...신기하구먼?


profile
모르는 것을 모른다고 하기

0개의 댓글