4

Account と Operator の 2 つのクラスがあります。アカウントにはオペレーターのリストが含まれています。ここで、オペレータ (リスト内) がメッセージを受信するたびに、ビジネス ロジックも実行するよう Account オブジェクトに通知したいと考えています。

これを達成する方法について、私は3つの選択肢を考えています。

1) Operator 内でコンテナー [Account] オブジェクトへの参照を保持し、メソッドを直接呼び出します。循環参照のため、絶対に良くありません。

2) イベントを使用します。私の知る限り、Python には組み込みのイベント処理メカニズムはありません。したがって、これを実装するのは少し難しいです。

3) オペレーターに直接メッセージを送らないでください。代わりに、アカウントのみを操作し、その内部でハンドラー オペレーターを操作します。この場合、演算子への参照を渡すことができないため、これには少し制限があります。

アーキテクチャの観点から、どのアプローチが最も有利なのだろうか。通常、このタスクをどのように処理しますか?

Python のスニペットを指摘していただけると助かります。

4

5 に答える 5

5

あなたはこれを考えすぎています。真剣に。Python は C++ ではありません。あなたの懸念はPythonの問題ではありません。問題のドメインで意味のあることを書くだけです。

「循環参照のため、絶対に良くありません。」

なぜだめですか?ここでは循環性はまったく関係ありません。双方向の関係は素晴らしいものです。それらを使用します。Python ガベージは、何も考えずに問題なく収集します。

相互 (双方向) の関係で、どのような問題が発生する可能性がありますか?

「...アカウントのみを操作し、その中で内部的にハンドラー オペレーターを操作します。この場合、オペレーターへの参照を渡すことができないため、これには少し制限があります。」

何?Operator は Python オブジェクトであり、必要なものをすべて渡します。すべての Python オブジェクトは (事実上) 参照です。気にしないでください。

Operator オブジェクトを操作する際にどのような問題が発生する可能性がありますか?

于 2009-04-29T12:15:23.200 に答える
3

これにはイベント処理を使用します。自分で実装する必要はありません-私はまさにこの種のイベント処理にpydispatcherを使用していますが、常に非常にうまく機能しています(循環参照の問題を回避するために、内部で弱参照を使用しています)。

また、GUI フレームワークを使用している場合は、フックできるイベント フレームワークが既にある可能性があります。たとえば、PyQtにはシグナルとスロットがあります。

于 2009-04-29T12:14:12.643 に答える
3
>>> class Account(object):
...     def notify(self):
...         print "Account notified"
...
>>> class Operator(object):
...     def __init__(self, notifier):
...         self.notifier = notifier
...
>>> A = Account()
>>> O = Operator(A.notify)
>>> O.notifier()
Account notified
>>> import gc
>>> gc.garbage
[]
>>> del A
>>> del O
>>> gc.garbage
[]

インスタンス メソッドについて知らないかもしれないことの 1 つは、ドット構文を使用する場合にルックアップされるとバインドされるということです。つまりA.notify、notify の self パラメーターを A に自動的にバインドすると言うことです。その後、収集不能なガベージを作成することなく、この関数への参照を保持できます。

最後に、この種のことにはいつでもカマエリアを使用できます。

于 2009-04-29T12:15:39.020 に答える
3

オブザーバー パターンには、「万能」なソリューションはありません。ただし、通常は、利害関係者が特定のイベントに自分自身を登録し、イベントが発生するたびにこれらのイベントを投稿できる EventManager オブジェクトを定義することをお勧めします。依存関係が少なくなるだけです。

グローバル EventManager インスタンスを使用する必要があることに注意してください。これは、テスト中または一般的な OO の観点から問題になる可能性があります (これはグローバル変数です)。コードが乱雑になるため、常に EventManager を渡すことはお勧めしません。

私自身のコードでは、イベントを登録するための「キー」はイベントのクラスです。EventManager は辞書 (イベント クラス -> オブザーバーのリスト) を使用して、どのイベントがどこに行くのかを認識します。通知コードではdict.get(event.__class__, ())、リスナーを見つけるために使用できます。

于 2009-04-29T12:00:25.203 に答える
0

Observer パターンのスニペットは Web のいたるところにあります。信頼できるコードの優れたソースは、アクティブ状態の EG です。

http://code.activestate.com/recipes/131499/

于 2009-04-29T13:00:07.960 に答える