전단 구조의 또 다른 방법


(이미지 출처: https://www.infoq.com/i18n/software-architecture-trends-2019)
본고는 추리하기 쉽고 유지보수성이 높은 프런트엔드 구조(Vue,React,Svelte 등을 사용하여 구축된 응용 프로그램에 적용)를 소개하고자 한다.만약에 중형/대형 응용 프로그램을 구축하고 있고 자신이 무엇을 생각하고 있는지 자주 발견한다면 이 글은 당신에게 도움이 될 것입니다.

양호한 구조의 장점
기술 문제에 대한 심도 있는 검토를 시작하기 전에 다음과 같은 작은 문제 하나를 해결하겠습니다.

(이미지 출처: https://pusher.com/tutorials/clean-architecture-introduction)
위의 그림에서, 너는 나에게 어떻게 테이프로 한눈에 호치키스를 바꿀 수 있는지 알려줄 수 있니?너희들 중 몇몇은 이 문제를 해결하기 위해 재미있는 방법을 생각해 낼 수 있지만, 우리 대다수의 사람들에게 우리는 이 문제를 해결할 방법을 즉각 찾을 수 없다.우리의 눈으로 볼 때, 그것은 마치 난마처럼 우리의 뇌를 곤혹스럽게 한다.
지금 이거 봐요.

(이미지 출처: https://pusher.com/tutorials/clean-architecture-introduction)
너는 지금 즉시 나에게 어떻게 호치키스를 교체하는지 알려줄 수 있니?우리는 그것과 연결된 밧줄을 풀고 테이프를 제자리에 놓으면 된다.이 점을 하려면, 너는 거의 어떤 정신적인 노력도 필요 없다.
위 그림의 모든 항목이 소프트웨어의 모듈이나 부분이라고 가정하십시오.좋은 구조는 두 번째 구조와 더욱 비슷해야 한다.이러한 아키텍처의 이점은 다음과 같습니다.
  • 항목에서 인지부하/정신노동을 감소한다.
  • 당신의 코드를 더욱 모듈화하고 느슨하게 결합시키기 때문에 테스트와 유지보수가 더욱 쉽습니다.
  • 아키텍처의 특정 부품을 교체하는 과정을 단순화합니다.

  • 공통 프런트엔드 아키텍처
    오늘날 프런트엔드 애플리케이션을 분리하는 가장 기본적이고 일반적인 방법은 다음과 같습니다.

    우선, 위의 구조는 아무런 문제가 없다.그러나 이런 구조는 흔히 볼 수 있는 모델로 구조의 일부분을 밀접하게 결합시킨다.예를 들어, Vue 3 및 Vuex 4로 작성된 간단한 카운터 응용 프로그램입니다.
    <template>
      <p>The count is {{ counterValue }}</p>
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
    </template>
    
    <script lang="ts">
    import { computed } from 'vue';
    import { useStore } from 'vuex';
    
    export default {
      name: 'Counter',
      setup() {
        const store = useStore();
        const count = computed<number>(() => store.getters.count);
    
        const increment = () => {
          store.dispatch('increment');
        };
    
        const decrement = () => {
          store.dispatch('decrement');
        };
    
        return {
          count,
          increment,
          decrement
        };
      }
    }
    </script>
    
    Vue 3과 Vuex로 작성된 프로그램에서 이것은 Vuex 4's guide 에 있기 때문에 매우 흔히 볼 수 있는 모델입니다.실제로 React with Redux 또는 Svelte with Svelte Stores도 일반적인 모델입니다.
  • React 및 Redux의 예:
  • import React, { useCallback } from 'react';
    import { useSelector, useDispatch } from 'react-redux';
    
    export const CounterComponent = () => {
      const count = useSelector(state => state.count);
      const dispatch = useDispatch();
    
      const increment = () => {
        dispatch({ type: 'increment' });
      };
    
      const decrement = () => {
        dispatch({ type: 'decrement' });
      };
    
      return (
        <div>
          <p>The count is {count}</p>
          <button onClick={increment}>+</button>
          <button onClick={decrement}>-</button>
        </div>
      );
    };
    
  • 날씬하고 날씬한 상점의 예:
  • <script>
      import { count } from './stores.js';
    
      function increment() {
        count.update(n => n + 1);
      }
    
      function decrement() {
        count.update(n => n - 1);
      }
    </script>
    
    <p>The count is {$count}</p>
    <button on:click={increment}>+</button>
    <button on:click={decrement}>-</button>
    
    이것들은 모두 본질적인 문제가 없다.사실상 대부분의 중대형 응용 프로그램은 이렇게 작성될 수 있다.그것들은 공식 지침서/강좌에서 추천하는 방법이다.
    그러나 모든 것은 일종의 균형이다.그렇다면 이런 모델의 장점과 단점은 무엇일까?
    가장 뚜렷한 장점은 간단할 수도 있다.
    그런데 이걸 위해서 뭘 희생했어?
    저장소와 구성 요소를 긴밀하게 결합했습니다.이제 Redux 가 더 이상 애플리케이션에 적합하지 않은 경우 (복잡하기 때문일 수 있음) 다른 애플리케이션으로 전환하고자 하는 경우 어떻게 해야 합니까?모든 저장소를 다시 써야 할 뿐만 아니라, Redux와 밀접하게 결합된 React 구성 요소의 논리도 다시 써야 합니다.
    같은 문제가 응용 프로그램의 모든 다른 층에서도 발생할 수 있다.마지막으로, 모든 것이 긴밀하게 결합되어 있기 때문에, 프로그램의 일부분을 쉽게 다른 것으로 바꿀 수 없습니다.가장 좋은 것은 그것을 상관하지 말고 처음부터 모든 것을 다시 쓰는 것이다.
    꼭 그럴 필요는 없어요.진정한 모듈화 체계 구조는 React+MobX(또는 Valtio), 심지어 더 미친 React+Vuex 또는 Vue+Redux(어떤 이유로든)로 React+Redux 응용 프로그램을 교체할 수 있어 응용 프로그램의 다른 부분에 영향을 주지 않는다.
    그렇다면, 우리는 어떻게 응용 프로그램의 일부분을 다른 부분에 영향을 주지 않고 바꿉니까? 아니면, 다시 말하면, 우리는 어떻게 응용 프로그램의 각 부분을 서로 결합시킵니까?

    다른 방법을 도입하다

    각 레이어의 피쳐는 다음과 같습니다.

  • 표시: 이 레이어는 기본적으로 UI 구성 요소로 구성됩니다.Vue의 경우 Vue SFC입니다.React의 경우 React 어셈블리입니다.날씬한 사람들에게는 날씬한 SFC다.잠깐만요.표현층이 응용층에 직접 결합되다.

  • 응용 프로그램: 이 층은 응용 프로그램 논리를 포함합니다.그것은 역층과 기초 구조층을 안다.이 체계 구조에서 이 층은 React의 React 갈고리나 Vue 3의 Vue'갈고리'를 통해 이루어진다.

  • 도메인: 도메인/비즈니스 논리에 사용됩니다.도메인 계층에는 비즈니스 논리만 존재하므로 여기에는 프레임/라이브러리가 없는 일반 JavaScript/TypeScript 코드만 있습니다.

  • 인프라: 이 층은 외부 세계와의 통신(요청/수신 응답)과 로컬 데이터 저장을 책임진다.이것은 실제 응용 프로그램에서 레이어에 사용되는 라이브러리의 예입니다.
  • HTTP 요청/응답: Axios, Fetch API, Apollo 클라이언트 등
  • 상점(상태관리): Vuex,Redux,MobX,Valtio 등

  • 응용 구조
    애플리케이션에 이 아키텍처를 적용하면 다음과 같습니다.

    위의 아키텍처 다이어그램에서 다음과 같은 특징을 확인할 수 있습니다.
  • UI 라이브러리/프레임을 교체하면 표시 및 애플리케이션 레이어에만 영향을 미칩니다.
  • 인프라스트럭처 계층에서 스토리지 구현 세부 사항(예: Redux를 Vuex로 교체하는 경우)을 대체할 때 스토리지 자체만 영향을 받습니다.
    악시오스를 Fetch API로 대체하는 것도 마찬가지이고 그 반대의 경우도 마찬가지입니다.응용층은 저장소나 HTTP 클라이언트의 구현 세부 사항을 모른다.다시 말하면, 우리는 이미 React와 Redux/Vuex/MobX를 결합시켰다.상점의 논리도 React뿐만 아니라 Vue나 Svelte에도 사용될 수 있을 정도로 통용된다.
  • 비즈니스 논리에 변화가 발생하면 도메인 계층을 수정해야 하며 이는 아키텍처의 다른 부분에 영향을 미칩니다.
  • 이 아키텍처는 더욱 흥미로운 점은 모듈식으로 구성할 수도 있다는 점입니다.


    경고
    비록 이 체계 구조는 응용 프로그램의 각 부분을 서로 분리할 수 있지만, 그것은 확실히 비용을 가져왔다. 그것은 복잡성을 증가시켰다.따라서 작은 프로그램을 개발하고 있다면, 이 프로그램을 사용하는 것을 권장하지 않습니다.큰 망치로 너트를 두드리지 마라.
    이 아키텍처는 더 복잡한 애플리케이션의 경우 다음과 같은 목표를 달성하는 데 도움이 될 수 있습니다.

    (이미지 출처: https://www.simform.com/react-architecture-best-practices)

    하나의 예
    나는 간단한 계수기 응용 프로그램을 구축하여 이런 구조의 장점을 보여 주었다.너는 여기서 원본 코드를 볼 수 있다. https://github.com/huy-ta/flexible-counter-app.

    이 프로그램에서, 나는 Vue, React, Vue와 Vuex, Redux, MobX, Valtio 심지어local Storage를 결합하여 사용한다.그것들은 모두 서로 영향을 주지 않는 상황에서 교체될 수 있다.자술한 파일의 간단한 설명에 따라 프로그램의 일부분을 다른 부분으로 전환해 보십시오.
    나는 이 카운터 프로그램에 대해 큰 망치로 너트를 두드리고 있다는 것을 알고 있지만, 복잡한 프로그램을 구축하는 것은 나에게 지금은 좀 불가능하다.그러나 Linagora에서 우리는 이러한 체계 구조를 우리의 프로젝트Twake Console에 응용하려고 시도하고 있다. 이 프로젝트는 곧 시작될 것이다.기대하세요.
    문제와 토론이 매우 환영을 받다😊.

    좋은 웹페이지 즐겨찾기