0

私のアプリケーションでは、特定のモジュールで変更が発生した場合、他のいくつかのモジュールに通知する必要があるというシナリオがあります。変更が発生するモジュールをサブジェクトとして保持し、通知されるモジュールをオブザーバーとして保持することにより、オブザーバー パターンがここに適合すると考えました。

しかし、オブザーバー パターンの原則に従うと、オブザーバーは互いに独立しています。オブザーバー間に接続があってはなりません。私の場合、モジュールは異なりますが、依存しています。最初のモジュールの実行が正常に完了することは、次のモジュールを実行するために重要です。また、モジュール x が失敗した場合、モジュール 1 によってモジュール x-1 に対して行われたすべての変更を元に戻す必要があります。つまり、すべてのモジュールが正常に実行されるか、以前の状態にロールバックする必要があります。トランザクションのように想像できます。それから、オブザーバー パターンがこれを実装する正しい方法ではないことが間違っていることに気付きました。

ここでは、主題の変更が発生したときに処理する必要があるモジュールのセットがありますが、制約により、モジュールは互いに依存しています。誰かがこの問題を解決して、良いデザインを考え出すのを手伝ってくれませんか?

4

3 に答える 3

1

取引部分について。実際、あなたの問題は、データベースで一連の更新操作を実行していて、1 つの失敗が以前のすべてを元に戻す必要があることです。

単純な解決策は、発信元の呼び出しをトランザクション スコープでラップすることです。

トランザクションの開始 A: データベースの更新 イベント B の更新: データベースの更新 イベント C の更新: データベースの更新 トランザクションの終了。

これはおそらくうまくいくでしょう!唯一の問題は、その間に計算がある場合、トランザクションの期間が長くなることです。トランザクションはできるだけ短くする必要があります。したがって、トランザクション中のリソースに関係のないアクションで、トランザクション中に時間を無駄にしないようにする必要があります。

上記の問題がある場合は、すべての更新コマンドを 1 つの場所 (遅延実行を db にラップするラムダ式のリスト) に蓄積し、すべての変更が蓄積されたらすぐに実行することができます。

于 2012-08-09T07:43:02.000 に答える
0

引き続きオブザーバーパターンを使用できます。必要なのは、イベントがオブザーバーを通過する方法を変更することだけです。

元の設計では、モジュールXが発生し、モジュールA、B、およびCにイベントが発生します。ただし、問題は、CがBに依存し、オブザーバーの実行の順序を制御しない(および制御したくない)ためです。 、問題があります。Aのオブザーバーではなく、CとBのオブザーバーを作成することをお勧めします。

このように、Aがイベントを発生させると、目的の順序で伝播します。A->B->C。

そうは言っても、本当にこのレベルのデカップリングが必要かどうか疑問に思います。基本的に、ここでは標準的な情報の流れを説明しています。モジュールが非常に再利用可能でない限り、明示的に呼び出しを行うことができます。AはBを直接呼び出し、BはCを直接呼び出します。

トランザクションは、データ伝播と直交する関心事です。私はあなたがそれらを別々に扱わなければならないのではないかと心配しています。ロールバックが必要になる可能性のある状態遷移について詳しく説明すると、コミュニティもそこで支援しようとする場合があります。

于 2012-08-09T05:44:01.770 に答える
0

オブザーバーに Composite と acquire-execute-release 構造を使用できます。これをオブザーバーと呼ぶかどうかはわかりませんが、コンポジットと組み合わせたトランザクションの抽象化に似ています。

インターフェイスは次のようになります。

public interface TransIf {
  boolean acquire();
  void execute() throws TransFailed;
  void release();
}
于 2012-08-09T08:46:48.283 に答える