web-dev-qa-db-ja.com

シンプルなタスクフレームワーク-再利用可能な部分からソフトウェアを構築する

私はいくつかのAPIを使用してWebサービスを作成しており、それらはいくつかの実装コードを共有します。コピーアンドペーストしないために、理想的には、各API呼び出しを、ビジネスロジックによって決定された順序で実行される一連のタスクとして実装したいと思います。

明らかな質問の1つは、それがコードの再利用に最適な戦略なのか、それとも別の方法で見ることができるのかということです。しかし、私がタスクを実行したいと仮定すると、いくつかの問題が発生します。

  1. 使用するのに適したタスクインターフェイスは何ですか?
  2. あるタスクで計算されたデータを、それを必要とする可能性のある順序で別のタスクに渡すにはどうすればよいですか?

過去に、私は次のようなタスクインターフェイスを使用しました。

interface Task<T, U> {
    U execute(T input);
}

次に、タスクが生成または消費するために必要なあらゆる種類のデータのゲッターとセッターを備えた一種の「タスクコンテキスト」オブジェクトもあり、それはすべてのタスクに渡されます。私はこれが多くの問題に苦しんでいることを知っています。そこで、今回はそれを実装するためのより良い方法を見つけたかったのです。

私の現在の考えは、タイプセーフな異種コンテナーであるTaskContextオブジェクトを用意することです(Effective Javaで説明されています)。各タスクは、このコンテナーからアイテムを要求する(タスク入力)か、コンテナーにアイテムを追加する(タスク出力)ことができます。そうすれば、タスクはお互いを直接知る必要がなく、データ項目ごとに数十のメソッドを持つクラスを作成する必要もありません。ただし、いくつかの欠点があります。

  1. このTaskContextコンテナの各アイテムは、実際のアイテムデータをラップする複合型である必要があります。タスクAが何らかの目的で文字列を使用し、タスクBがまったく異なる目的で文字列を使用する場合、String.classと一部のオブジェクトの間のマッピングを格納するだけでは、両方のタスクで機能しません。もう1つの理由は、この種のコンテナーをジェネリックコレクションに直接使用できないため、別のオブジェクトでラップする必要があるためです。

  2. つまり、定義するタスクの数に基づいて、消費または生成される可能性のあるタスクアイテムのクラスの数も定義する必要があり、コードの膨張や重複が発生する可能性があります。たとえば、タスクが入力としてLong値を取り、出力として別のLong値を生成する場合、Longを単純にラップする2つのクラスが必要になります。これは、コードベースが進化するにつれてIMOが制御不能になる可能性があります。

ワークフローエンジンライブラリを簡単に調べましたが、これらはこの特定の釘にとって重いハンマーのように見えます。次の要件を持つ単純なタスクフレームワークをどのように作成しますか。

  • タスクは可能な限り自己完結型である必要があります。これにより、タスクをさまざまな方法で構成して、さまざまなワークフローを作成できます。

  • そうは言っても、一部のタスクは、他のタスクの前提条件である高価な計算を実行する場合があります。他のタスクがそれらの結果を無料で使用できるように、タスクによって実行された中間計算の結果を保存する方法が必要です。

  • タスクフレームワークは軽量である必要があります。つまり、コードを拡張するために、フレームワークにプラグインするためだけに多くの新しいタイプを導入する必要はありません。

3
RuslanD

TaskContextコンテンツの汎用ラッパーを作成する必要があります。 Thulasiが言うように、これには他の誰かのラッパーを使用してください。 JSON、XML、必要に応じて一時ファイル、さらには適切なデータベースなど。物事を軽くしたい場合は、コードの再利用が最適です。

タスクコーディネーターと一連のタスクを実行すると、間違いなく何らかの通信が必要になります(今すぐ停止してください!)。その後、共通データストアが大きくなり、制限する必要があります。キャッシュがより重要になります。 ...そしてあなたはあなた自身のフレームワークを持つでしょう。既存の「重い」フレームワークに切り替わる前に、その道をどこまで進んでいくのかを正確に把握することをお勧めします。

私の提案は、「コミュニケーションなし」に自分を制限することです。迅速に実行され、無害に強制終了できるファイアアンドフォーゲットタスクしかない場合(つまり、データストアがトランザクションである場合)、問題はかなり扱いやすくなります。それ以上のものであれば、フレームワークを扱うほうがよいでしょう。要件が単純な場合、フレームワークの関与を最小限に抑えることができない理由はありません。

1
Chris Digi