コンテナオブジェクトへの通知:ベストプラクティス
-
03-07-2019 - |
質問
アカウントとオペレーターの2つのクラスがあります。アカウントにはオペレーターのリストが含まれています。ここで、(リスト内の)オペレーターがメッセージを受信するたびに、ビジネスロジックを実行するようにAccountオブジェクトに通知する必要があります。
これを達成する方法について、3つの選択肢があると思います:
1)Operator内でコンテナ[Account]オブジェクトへの参照を保持し、メソッドを直接呼び出します。循環参照のため絶対に良くありません。
2)イベントを使用します。私の知る限り、Pythonには組み込みのイベント処理メカニズムはありません。したがって、これは実装するのが少し難しいです。
3)オペレーターに直接メッセージを送信しないでください。代わりに、アカウントのみを操作し、アカウント内で内部的にハンドラー演算子を操作します。この場合、演算子への参照を渡すことができないため、これは少し制限されています。
どのアプローチがアーキテクチャの観点から最も有利であるのだろうか。このタスクは通常どのように処理しますか?
Pythonでスニペットを指摘できたら素晴らしいと思います。
解決
あなたはこれを考えすぎています。真剣に。 PythonはC ++ではありません。あなたの懸念はPythonの問題ではありません。問題のあるドメインで意味のあることを書くだけです。
"循環参照のため絶対に良くありません。"
どうして?ここでは、循環性はまったく関係ありません。双方向の関係は素晴らしいことです。それらを使用します。 Pythonのガベージコレクションは、何も考えずに問題なく収集します。
相互(双方向)の関係で考えられる問題は何ですか?
" ...アカウントのみを操作し、アカウント内では内部的にハンドラー演算子を操作します。この場合、演算子への参照を渡すことができないため、これは少し制限されています。 "
何?演算子はPythonオブジェクトであり、必要なものをすべて渡します。すべてのPythonオブジェクトは(実質的に)参照であり、気にしないでください。
Operatorオブジェクトの操作に関してどのような問題がありますか?
他のヒント
「万能なもの」はありませんObserverパターンのソリューション。ただし、通常は、関係者が特定のイベントに自分自身を登録し、これらのイベントが発生するたびにポストできるEventManagerオブジェクトを定義する方が適切です。作成される依存関係が少なくなります。
グローバルEventManagerインスタンスを使用する必要があることに注意してください。これは、テスト中または一般的なオブジェクト指向の観点から問題になる可能性があります(グローバル変数です)。 EventManagerを常に渡すことは強くお勧めします。コードが混乱するからです。
自分のコードでは、" key"イベントを登録するためのイベントのクラスです。 EventManagerはディクショナリ(イベントクラス->オブザーバーのリスト)を使用して、どのイベントがどこに行くかを認識します。通知コードでは、 dict.get(event .__ class__、())
を使用してリスナーを見つけることができます。
これにはイベント処理を使用します。自分で実装する必要はありません-この種のイベント処理のために pydispatcher を使用し、常に非常にうまく機能します(循環参照の問題を回避するために、内部で弱参照を使用します)。
また、GUIフレームワークを使用している場合は、たとえば PyQt にはシグナルとスロットがあります。
>>> 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にバインドされます。収集できないガベージを作成することなく、この関数への参照を保持できます。
最後に、この種のことにはいつでも Kamaelia を使用できます。
Webには、Observerパターンスニペットがあります。信頼性の高いコードの優れたソースは、アクティブ状態、E.Gです: