중재자 패턴 자체 생성 문서

중재자 정보



중재자는 구성 요소를 구축하고 Api 호출과 상호 작용하기 위한 UI/UX 패턴입니다. 중재자 패턴을 사용하여 UI/UX는 보다 쉬운 테스트 및 재사용성을 위해 마이크로 서비스 아키텍처를 유지할 수 있습니다.


데이터 흐름의 그래프 표현





이 예에는 GRPC Api와 GRPCApi를 모방한 모의 Api가 모두 있습니다. 이를 통해 대신 단순히 MockApi를 호출하여 백엔드 메서드를 반복적으로 누르지 않고도 구성 요소와 논리를 테스트할 수 있습니다.


ApiMediator 예



ApiMediator는 클래스 정의 및 기능을 정의하는 곳입니다. 아래는 구현 예입니다.

export class AnimalMediatorExample {
  private api: AnimalApi;
  animal = new AsyncActionRunner({name: "cat", legs: 4});
  changedAnimalsCount = new ObservableValue(0);

  constructor(api: AnimalApi){
    this.api = api;
  }
  getBigCat() {
    const action = new AsyncAction(()=>{
      const [request, cancel] = this.api.getBigCat(); // returns Promise.resolve({name:"lion", legs: 4});
      action.onCancel(cancel); // optional method
      return request;
    });

    changedAnimalsCount.setValue(changedAnimalsCount().getValue()++);

    return this.animal.execute(action);
  }
  getSmallCat() {
    const action = new AsyncAction(()=>{
      return this.api.getSmallCat(); // returns Promise.resolve({name:"bobcat", legs: 4});
    });

    changedAnimalsCount.setValue(changedAnimalsCount().getValue()++); 

    return this.animal.execute(action);
  }
}
...

AsyncAction s: Promise 의 기능을 확장하여 실행을 재시도하고 취소할 수 있습니다.
AsyncActionRunner : 비동기 값만 처리하도록 확장합니다ObservableValue.
이를 위해 AsyncAction 를 실행하고 해당 작업의 상태를 당사자에게 알립니다. AsyncActionRunner는 다음 속성을 저장합니다.
  • 상태: "초기"| "보류 중"| "성공"| "오류"| "비활성화됨"
  • 값: { name: string, legs: number } // From AnimalMediatorExample
  • 오류: 모두

  • 이러한 속성은 무기한 업데이트할 수 있으며 구성 요소에서 구독할 수 있습니다.ObservablesSubjects에 대한 자세한 내용은 RxJs을 참조하십시오.

    참고: AsyncActionRunner는 업데이트될 때마다 구성 요소 다시 렌더링을 트리거합니다.

    ApiProvider 예



    import React, { useMemo, useEffect } from 'react';
    import { AnimalMediatorExample } from './AnimalMediatorExample';
    import { MockApi } from './MockApi';
    import { IApi } from './IApi';
    
    export const AnimalContext = React.createContext(new AnimalMediatorExample(new MockApi()));
    
    export interface Props {
      children?: React.ReactNode | React.ReactNode[];
      api?: IApi;
    }
    
    const AnimalProvider = ({ api, children }: Props) => {
      const mediator = useMemo(() => {
        if (api != null) {
          return new AnimalMediatorExample(api);
        } else {
          return new AnimalMediatorExample(new MockApi());
        }
      }, [api]);
    
      useEffect(() => () => mediator.dispose(), [mediator]);
    
      return (
        <AnimalContext.Provider value={mediator}>{children}</AnimalContext.Provider>
      );
    };
    
    export default AnimalProvider;
    
    AnimalProvider에서 우리는 모든 하위 구성 요소에 전달할 수 있는 컨텍스트를 생성합니다. 이것은 클래스AnimalMediatorExample를 인스턴스화하고 속성 및 함수에 액세스할 수 있도록 로컬 const에 저장하는 것과 유사합니다.
    AnimalProvider에 대한 반응 예제 사용

    import React from 'react';
    import AnimalProvider from './AnimalProvider';
    import CatComponent from './CatComponent';
    
    const AnimalProviderWrapper = () => {
      return (
        <AnimalProvider> //or can pass in as a prop an Api to override the MockApi <AnimalProvider api={AnimalApi}>
          <CatComponent />
        </AnimalProvider>
      );
    };
    


    이렇게 하면 <CatComponent />가 AnimalMediator 컨텍스트에 액세스할 수 있습니다.

    More information on React Context can be found here

    컨텍스트 제공자 예의 중재자 데이터를 사용하는 기능적 구성 요소

    import React from 'react';
    import { useAsyncValue } from '@operator/shared/utils/mediator/hooks/useAsyncValue';
    import { AnimalContext } from './AnimalProvider.tsx';
    
    const CatComponent = () => {
      const mediatorContext = React.useContext(AnimalContext);
      const bobCat = useAsyncValue(mediatorContext.getSmallCat()); //useAsyncValue returns the value insde of the promise { name: 'bobcat', legs: 4 }
      return (
        <div>
          <p>I Have a pet {bobCat.name}</p>
        </div>
      );
    }; 
    


    참고: useAsyncValue는 Promise 내부의 값을 검색하기 위해 빌드된 사용자 지정 후크입니다.


    구성 요소에 대한 테스트 작성에 대한 참고 사항



    Jest는 때때로 우리의 새로운 중재자 패턴으로 이상한 오류를 던질 것입니다. 오류 세부 정보는 일반적으로 명확하지 않지만 문제가 발생한 위치를 명확하게 하는 데 도움이 되는 몇 가지 사항은 컨텍스트에서 테스트 구성 요소를 래핑하고 제공되었는지 확인하는 것입니다. 모카피.

    const mockApi = {
      getSmallCat: jest.fn().mockImplementation(() => [Promise.resolve(), () => {}]),
      getBigCat: jest.fn().mockImplementation(() => [Promise.resolve(), () => {}]),
    };
    test('Should Display Animal Component', () => {
      render = (
        <AnimalProvider api={mockApi}>
          <CatComponent />
        </AnimalProvider>
      );
    ...
    



    중재자 원칙



    단일 책임 원칙



    중재자는 하나의 책임을 갖고 잘 수행해야 합니다.

    YAGNI - 당신은 그것을 필요로하지 않을 것입니다



    중재자는 데이터를 구성 요소에 전달하기 위해 많은 유형 변환기가 필요하지 않습니다. 많은 변환기와 메서드를 추가하면 중재자 패턴의 단순성이 어수선해집니다.

    좋은 웹페이지 즐겨찾기