티스토리 뷰

 1편에 이어 React에서 MVVM패턴을 사용하는 방법을 이어 진행하겠습니다. 1편 마지막에 Service 단에 Counter를 직접 들고 있는 형태의 구조가 나왔는데 실제로는 Repository를 이용해 모델 데이터를 관리하게 됩니다.

 

 모델 데이터의 저장과 불러오기를 Repository를 통해 사용하며 Repository는 실제 API를 통해 데이터를 가져오는데도 역할을 하게 됩니다. 하지만 많은 실제 API를 통해 받아오는 데이터는 불규칙하며 페이지 별로 상이하기 때문에 DTO에 맞춘 여러 변형 객체를 여러개 소장하고 있어야 합니다. (GraphQL을 활용한다면 완전한 Repository를 구성할 수 있지 않을까라는 생각도 되네요)

1. Repository

import Counter from "./counter";

class CounterRepo {
  private counter?: Counter = new Counter();

  public get() {
    return this.counter;
  }

  public save(counter: Counter) {
    this.counter = counter;
  }

  public remove() {
    this.counter = undefined;
  }
}

export default CounterRepo;

 Counter를 관리하는 CounterRepo입니다. Counter객체를 가지고 있으며 해당 객체의 생성, 불러오기, 삭제 그리고 API에 대한 통신을 담당하며 비즈니스 로직을 포함하지 않습니다.

*API를 호출할 때는 API의 이름과 동일하게 맞춰주도록 합니다.

 

CounterRepo를 이렇게 변경하면서 Service를 함께 변경해줘야합니다.

 

2. Service 변경

import { action, makeAutoObservable } from "mobx";
import { GlobalService } from "..";
import Counter from "./counter";
import CounterRepo from "./counterRepo";

class CounterService {
  counterRepo;

  constructor(counterRepo: CounterRepo) {
    this.counterRepo = counterRepo;
  }

  addCount() {
    const counter = this.counterRepo.get();
    counter?.plus();
  }

  minusCount() {
    const counter = this.counterRepo.get();
    counter?.minus();
  }

  get count() {
    return this.counterRepo.get()?.value;
  }
}

export default CounterService;

 가장 먼저 constructor를 통해 CounterRepo를 주입받습니다. (추후 자동으로 주입해줬으면...) 각 함수는 Repository를 통해 데이터를 불러오고 비즈니스 로직을 수행합니다. 저의 경우 Counter객체를 observable로 설정했기에 Repo와 Service에 아무런 Mobx 처리를 해주지 않았지만 Service의 함수에 action을 설정하는 방법도 존재합니다.

 

이제 constructor에서 주입받는 방법을 알아보겠습니다.

 

3.  GlobalStore

import { createContext } from "react";
import CounterRepo from "./counter/counterRepo";
import CounterService from "./counter/counterService";

export class GlobalStore {
  counterRepo = new CounterRepo();
  counterService = new CounterService(this.counterRepo);
}

const instance = new GlobalStore();
const Context = createContext<GlobalStore>(instance);
export default Context;
export { instance };

GlobalStore는 React를 이용해 Context에 만들어 모델연관 객체들을 관리하게 됩니다. 여기서 Repo와 Service들을 실제 생성하며 각 객체를 생성할 때 필요 연관관계를 주입해주게 됩니다. 객체의 별도 관리를 통해 결합도를 낮출 수 있습니다. 또한 Context의 특성으로 단일 객체로 관리 할 수 있다는 장점도 존재합니다.

 

패턴에서 사용하는 여러 객체와 레이어들을 정리해 보았는데 생각과 철학을 글로 정리한다는게 얼마나 어려운지 한 번더 느끼게 됐습니다.. 3편에는 조금 더 예제를 탄탄히 하여 처음부터 끝까지 흐름을 정리해 볼 수 있도록 해보겠습니다.

 

git link: https://github.com/JeongYS/react-mvvm-practice

반응형

'개발' 카테고리의 다른 글

나아가기 위해 버린다  (0) 2022.09.15
Service와 Interface  (0) 2022.09.14
악마는 디테일에 있다  (1) 2022.07.11
My React OOP + MVVM practice (feat. OOP, Typescript) (1)  (0) 2022.06.21
사이드 프로젝트 기술 스택 선정  (0) 2022.05.22
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함