1

複数の状態を持つことができる、タスクに相当するエンティティがあります。「タスク」は、保留中、合格、または失敗のいずれかの状態になります。これらの各状態には、いくつかの固有のデータもあります。たとえば、失敗した状態では、エンティティには失敗の理由が必要であり、保留中の状態では、評価の期限が必要です。

上記のことから、各状態を表す個別のオブジェクトが必要であると考えるようになりましたが、エンティティの基になる ID は同じままにする必要があるため、これを単一のオブジェクトと考える方向に後退しました。

また、状態から状態への遷移にはいくつかのロジックが必要です。「合格」状態に遷移する「保留」タスクは、同じ遷移を行う「失敗」タスクとは異なる方法で処理されます。

各状態の表現がまったく同じである場合は、プリミティブ プロパティを使用するだけで済みます。ただし、州ごとに表現がわずかに異なるため、これをモデル化する最善の方法を見つけるのに苦労しています。内部状態を管理するためのロジックがややこしくなってきているので、一歩下がって再考することにしました。何かご意見は?

私はこの言語にとらわれないと考えていますが、私はc#を使用しています。

4

5 に答える 5

1

この質問を最初に読んだとき、私の答えは列挙を使用して状態を定義することでした。しかし、それを読み直した後、次のいずれかをお勧めします。

  1. 各タスクを、同じ親を持つ個別のクラス (PendingTask、PassedTask など) として実装し、その状態の前にある任意のタイプのタスクを受け入れるコンストラクターを実装します。
  2. 1 つの Task を実装し、各状態に必要なデータの子クラスを持つ新しいクラス TaskStateData を作成します。
  3. 1 つのタスクを実装しますが、その状態に必要な追加の属性のパラメーターを使用して、状態の種類ごとに状態を変更する別のメソッドを用意します。

データの整合性を確保するために、これらのソリューションをお勧めします。

于 2010-01-25T18:05:40.017 に答える
1

「タスク」は、保留中、合格、または失敗のいずれかの状態になります。「合格」状態に遷移する「保留」タスクは、同じ遷移を行う「失敗」タスクとは異なる方法で処理されます。

これはかなり奇妙な状態のコレクションのようです。タスクの実行には時間がかかると予想されるため、保留中から実行中への移行は成功または失敗し、時間切れになる前に実行されないタスクは期限切れになります。また、failed から failed-and-expired への移行がある場合は、別の状態が追加される可能性があります。

状態を見つけるためにステート マシンを描画します。

まず、状態を構造的にモデル化する必要がありますか? 保留中/期限切れのフラグ、スケジュールされた時間、および結果は機能しますか (結果の 2 つのサブタイプとして失敗と成功があります)? タスクのクライアントはそれから何を必要としますか?

次に、タスクまたはスケジューラと対話していますか? スケジューラにタスクの説明を与えて、タスクの結果について照会できる未来を取得することは珍しくありません。ただし、タスク自体は公開されず、完了したかどうかと結果のみが公開されます。進行状況が必要な場合は、参照を保持しているタスク オブジェクトではなく、タスク ID でクエリを実行して進行状況を取得できるスケジューラが必要になる場合があります。状態が同時に変化するタスク オブジェクトがあると、一貫したセットを取得するのが難しくなります。最終状態に到達するまで、それから状態データを取得します。「合格」状態に失敗情報がない場合、「失敗したか」をクエリし、続いて「失敗ステータスを取得」すると、ロック (ewww) を外部化しない限り、簡単に競合が発生します。

于 2010-01-25T21:44:13.543 に答える
1

純粋なオブジェクト指向のアプローチには欠点があります。多くのポリモーフィック コード管理を行う予定がない限り、ポリモーフィズムを直接使用してドメイン クラスの状態を表すことは避けてください。私はよりハイブリッドなアプローチに落ち着きました。異なる状態は、別個の親子継承ツリーとしてモデル化する必要があります。子として MyState1、MyState2、および MyState3 を持つ抽象基本クラス MyState から始めます。(例については、ジェフリーの回答を参照してください。

状態を追跡する必要があるエンティティには、MyState 型の「current-state」属性があります。エンティティが状態を変更するとき、それを変更するのは単純な代入または setter() 呼び出しです。必要に応じて、各状態のシングルトン インスタンスを構築したり、状態の変化ごとに新しいインスタンスを構築したりできます。状態が変化する頻度と、状態が追跡されているオブジェクトの数によって異なります。数値が大きくなりすぎる場合は、シングルトン アプローチを検討できます。

于 2010-01-25T21:00:21.663 に答える
0

状態パターンを見てください。

于 2010-01-25T17:51:37.277 に答える
0

これは、オブジェクトの継承とポリモーフィズムの理想的なアプリケーションのように思えます。

abstract class Task
{
      public int TaskId { get; private set; }
      abstract PassedTask TransitionToPassed();
      ...
}

class PendingTask : Task
{
      PassedTask TransitionToPassed()
      {
            PassedTask passed = new PassedTask();
            passed.TaskId = TaskId;
            ...
            return passed;
      }
      ...
}

class PassedTask : Task
{
      PassedTask TransitionToPassed()
      {
            return this;
      }
      ...
}

class FailedTask : Task
{
      public string ReasonForFailure { get; private set; }
      PassedTask TransitionToPassed()
      {
            ...
      }
      ...

}
于 2010-01-25T18:04:21.453 に答える