Mediatorパターン自己作成ドキュメント


について


Mediatorは、コンポーネントを構築するためのUI/UXパターンであり、APIの呼び出しとの対話は、Mediatorパターンを使用して、UI/UXは、簡単にテストと再利用性のためのマイクロサービスアーキテクチャを維持することができます.

データフローのグラフ表現



この例では、grpcapiを使用しているGRPC APIとmock APIを持っています.これにより、単純にモックアップを呼び出すだけでバックエンドメソッドを繰り返しヒットすることなく、コンポーネントとロジックをテストできます.

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 Sを実行し、そのアクションのステータスの任意の当事者に通知します.AsyncActionRunnerには以下のプロパティが格納されている:
  • ステータス:“初期”の“保留”“成功”“エラー”“”“エラー”“”
  • の値:{ name: string, legs: number } // From AnimalMediatorExample
  • エラー:任意242479182
    これらのプロパティは、無期限に更新することができ、コンポーネント内で購読することができます.Observables及びSubjectsの詳細については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は、約束の値を取得するためのカスタムフックです

    部品の筆記試験ノート


    ジェスは時折私たちの新しいメディエーターパターンで奇妙なエラーをスローします、エラーの詳細は通常、非常に明確ではありませんが、問題がどこから来ているかを明確にすることができるいくつかのことは、コンテキストでテストコンポーネントをラップして、それがmockapiを提供することを保証することです.
    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>
      );
    ...
    

    仲介者原則


    単一責任原則


    仲介者は1つの責任を持って、それをうまくやるべきです.

    Yagni -あなたは、それを必要とするつもりです


    メディエータは、コンポーネントにデータを渡すために、タイプコンバータの束を必要としません.私は多くの変換器とメソッドを追加するには、mediatorのパターンのシンプルさをclutters気づいた.