2

私は(私が望んでいた)やや単純なワークフローエンジンを考え出そうとしています。

基本的に、私はStatusプロパティを持つクラスのオブジェクトを持っています。別のステータスに進むには、検証ステップを通過する必要があります。検証エラーがない場合、ステータスは変更されます。

ただし、検証中に、検証コンポーネントがユーザーからの情報を要求したり、警告メッセージを発行したりできるようにしたいと考えています。

私の問題は、現時点ではアプリケーションが Windows フォーム アプリケーションとして構築されていることですが、Web バージョンが必要になることがわかっています。したがって、検証は両方で同じになりますが、情報を要求したり、ユーザーに警告したりする独自の方法をそれぞれに許可する必要があります。私が想像した方法は、検証クラスでデリゲートとイベントを使用することです。

これが私が得たものです:

//This is the class which will have its status changed
public class MyClass
{
  public int Status { get; set; }
}

//This class represent a transition from one status to another
public class Transition
{
  public int FromStatus { get; set; }
  public int ToStatus { get; set; }
}

//Common interface for all validators
public interface IWorkflowValidator
{
  bool Validate(MyClass object);
}

//This is the base workflow class with the main logic
public abstract class BaseWorkflow
{
  //This holds all the possible transitions with the validator type responsible for its validation.
  //For example:
  //  var transition = new Transition(1, 2); //From 1 to 2
  //  validatorsMap.Add(transition, typeof(ValidatorFrom1To2)); //ValidatorFrom1To2 class would be used to validate transition from status 1 to 2.
  protected Dictionary<Transition, Type> validatorsMap = null;

  //Main logic for a transition
  public void PerformTransition(MyClass object, int ToStatus)
  {
    int currentStatus = object.Status;
    var requestedTransition = new Transition(currentStatus, ToStatus);

    //Get the validator specified for this transition
    var validatorType = validatorsMap[requestedTransition];

    //Instantiate a new validator of that type
    var validator = (IWorkflowValidator)Activator.CreateInstance(validatorType);

    //Gets the result of the validator
    bool results = validator.Validate(object);

    //If validation succeded, it will perform the transition and complete the execution
  }
}

私の主な質問は、バリデータ自体に関するものです。前述したように、特定のトランジションに必要な情報を要求できるバリデーターが必要です。だから、これは私が最初のバリデータを持っている方法です:

public class AlertHandlerArguments {}

public delegate void AlertHandler(AlertHandlerArguments args);

public class MyFirstValidator : IWorkflowValidator
{
  //Event used to send an alert to the user
  public event AlertHandler OnAlert;

  //Implementation of IWorkflowValidator
  public bool Validate(MyClass object)
  {
    SendAlert();
  }

  void SendAlert()
  {
    if (OnAlert != null)
      OnAlert(new AlertHandlerArguments());
  }
}

ここで私が考えているのは、すべてのタイプのイベントとのインターフェースを作成し、それらをすべてのバリデーターに実装することです。次に、抽象BaseWorkflowクラスは、これらのイベントのハンドラーをアタッチできます。

ただし、私の抽象クラスは、これらのイベントの最終的なコードを実装できません。これらはインターフェイスによって使用されることを意図しており、これまでのところ、私の抽象クラスはプラットフォームに依存しません (デスクトップ、Web)。それが実際に、このクラスを抽象クラスとして作成した理由です。

これで、Windows フォーム プロジェクトにBaseWorkflowの具象型を持たせ、イベントをアタッチして Form オブジェクトを表示し、情報を要求することができます。

もう 1 つのオプションは、基本クラスにハンドラーをアタッチし、UI レベルで具象クラスをオーバーライドすることです。

私は正しい方向に進んでいますか?バリデーターが (UI レベルで) ユーザーからの情報を要求できるようにするにはどうすればよいですか?

この件に関するご意見をお待ちしております。前もって感謝します。

Ps .: 書き終わって初めて、これを Web アプリケーションで使用する方法がよくわからないことに気付きました。つまり、Windows フォーム アプリケーションは実行を中断してユーザーの入力フォームを表示できますが、それは Web 上では機能しません。これは、私のワークフロー構造がデスクトップ アプリケーションに対してのみ実行可能であることを意味しますか?

4

1 に答える 1

4

まず第一に、ワークフロー内でさまざまなバリデーターを使用したい場合、バリデーターは環境に依存します => したがって、おそらく戦略パターンが必要です。しかし、それには注意が必要です。

すべてのタイプのイベントとのインターフェースを作成することは、やることのやり過ぎのため、おそらく完璧なアイデアではありません。そのバリデータには公開状態が必要であり、その状態は検証結果に依存する可能性があり、ワークフローはバリデータの状態をチェックするだけです。イベントを使用する代わりに、関数の引数としてデリゲートを使用する方が良いと思います。

于 2013-01-17T20:21:51.570 に答える