Mediatorパターン自己作成ドキュメント
16734 ワード
について
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
には以下のプロパティが格納されている:
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);
}
}
...
{ name: string, legs: number } // From AnimalMediatorExample
これらのプロパティは、無期限に更新することができ、コンポーネント内で購読することができます.
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気づいた.
Reference
この問題について(Mediatorパターン自己作成ドキュメント), 我々は、より多くの情報をここで見つけました https://dev.to/davidcf/mediator-pattern-documentation-2jb1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol