6

(もしあれば) 暗黙の仮定や制限、および設計の違いは何ですか:

A) これ:

class SampleClass1
{
    IWorker workerA;
    IWorker workerB;

    void setWorkerA(IWorker w);
    void setWorkerB(IWorker w);
    WorkResult doWork();
}

B) 対これ:

class SampleClass2
{
    WorkResult doWork(IWorker workerA, IWorker workerB);
}

特定のプロジェクトに依存することはわかっていますが、上記のクラスが小さなフレームワークの一部である場合はどうなりますか? 最初のクラスは状態を維持し、ステップをより自然に分離できますが、2番目のクラスは doWork() が呼び出されるたびに Worker が渡されるため、外部呼び出し元との「リアルタイム通信」がより自然に保証されます。

上記の 2 つの方法のどちらかを選択するための推奨される使用方法や一般的な方法はありますか? ありがとう。

4

8 に答える 8

6

SampleClass1

  • doWork 間でワーカーの状態を維持する必要がある場合があります
  • ワーカーを個別に設定する機能が必要になる場合があります。(1 と 2 で作業し、次に 2 と 3 で作業する)
  • 同じワーカーで doWork を複数回実行することが予想される可能性があるため、ワーカーを維持したいと考えています。
  • 私はユーティリティクラスではありません。私の例は重要です。

SampleClass2

  • ワーカーを 2 人ください。一緒に仕事をします。
  • 私は彼らが誰であるかは気にしませんし、維持したくありません。
  • ワーカー間のペアリングを維持するのは、他の誰かの仕事です。
  • 私はもっ​​とユーティリティクラスかもしれません。多分私はただ静的になることができます。
于 2008-09-26T09:10:57.980 に答える
5

オプション (A) では、Function Object または Functor として知られているものを作成しています。これは十分に文書化されている設計パターンです。

主な利点は次の 2 つです。

  • ワーカーをある場所で設定してから、オブジェクトを別の場所で使用できます
  • オブジェクトは呼び出し間で状態を保持できます

また、依存性注入フレームワーク (Spring、Guice など...) を使用している場合、ファンクターは自動的に初期化され、必要な場所に注入されます。

関数オブジェクトは、C++ 標準テンプレート ライブラリなどのライブラリで広く使用されています。

于 2008-09-26T09:26:48.753 に答える
2

ケース A の変形である別のオプションは次のとおりです。

クラス SampleClass3
{
    SampleClass3( IWorker workerA, IWorker workerB );
    WorkResult doWork();
}

利点:

  • (ケース A とは対照的に) 構築時に必要なすべてのワーカーを提供する必要があるため、オブジェクトを欠陥品にすることは困難です。

  • SampleClass3 および/またはいずれかのワーカー内で状態を保持できます。(ケースBでは不可能です。)

短所:

  • 後で提供できるようにするのではなく、SampleClass3 を構築する前にすべてのワーカーを準備する必要があります。もちろん、後で変更できるようにセッターを提供することもできます。
于 2008-09-26T10:01:12.930 に答える
1

複数のメソッドが IWorker a と IWorker b に依存している場合は、サンプル A を実行します。

doWork() のみが IWorker a と IWorker b の両方を使用する場合は、サンプル B を実行します。

また、SampleClass の本当の目的は何ですか? doWork は、何よりもユーティリティ メソッド mroe に少し似ています。

于 2008-09-26T09:05:58.430 に答える
1

A) オブジェクトに欠陥がある可能性があるため、悪い設計です (1 つまたは両方のワーカー クラスが設定されていない可能性があります)。

B)良いことができます。ただし、SampleClass2 の内部状態に依存しない場合は静的にします

于 2008-09-26T09:08:22.497 に答える
0

IMO 2 番目のアプローチの方が見栄えがよく、呼び出し元がタスクを実行するために使用するコードを少なくする必要があります。2 番目のアプローチはエラーが発生しにくく、呼び出し元はオブジェクトが完全に初期化されていない可能性があることを心配する必要はありません。

于 2008-09-26T09:08:37.690 に答える
0

代わりに、単に a を返すa WorkDelegate(または引数のない単一のメソッドを持つインターフェイス) を定義し、個々のクラスにそれを実装する方法を決定させるのはどうですか? こうすることで、時期尚早の決定にとらわれることがなくなります。doWorkWorkResult

于 2008-09-26T09:08:47.863 に答える
0

別のオプション:

IWorker クラス:

static WorkResult doWork(Iworker a, Iworker b);

于 2008-09-26T09:03:22.913 に答える