4

Pythonを使用してアプリケーションを作成しています。

私は最初にAPIを設計しましたが、これは正常に機能しています。現在、GUIを設計しています。GUIは、APIに対してタスクを実行するために使用されるスレッドを開始します。

これまで、私はObserverパターンを使用して、さまざまなレイヤーを介した通信を処理していました。基本的に、通信には次の2つのタイプがあります(主に)。-スレッド(およびその後のAPI)にSTART /STOPを要求するGUI-GUIに伝播する情報をスレッドに返すAPI。

これが私が話している現在のアーキテクチャの簡単なスキーマです。基本的に、1つの矢印は「通知」を意味します。

現在のオブザーバー/監視可能な通信

私の懸念は、アプリケーションスレッドが通信するときに、GuiとAPIの両方がサブスクライブしているためにメッセージを受信することです。つまり、各メッセージは2つのうちの1つだけが読むことを目的としています。

それを解決するために私がしたことは、IDと一緒にメッセージを送信することです。3つの要素のそれぞれにIDがあり、メッセージが自分宛であるか現在のものであるかを認識しています。しかし、これが「正しい」(最もよく理解されている)方法であるかどうかはわかりません。将来、パーティーが増えるとどうなりますか?

私はコミュニケーションを処理するある種のマネージャーについて考え始めましたが、それはアーキテクチャの最上位になければならず、それをさらに整理する方法がわかりません:s。

私は完全な解決策を求めているのではなく、主に経験豊富な人々によるアイデアやベストプラクティスを求めています;)

この単純なケースでは、複数のオブザーバーパターンを処理し続けることができます。しかし、私は自分のコードをサーバーに移植することを考えていました。この場合、アプリケーションに複数のスレッドがある可能性が高く、API呼び出しの処理はまったく不可能になります。

私が話しているコードへのリンク: GUIApplicationThreadApplicationAPI

通知メソッドと更新メソッドを確認します。

アドバイスをお願いします!

4

4 に答える 4

3

私が出会ったオブザーバーパターンの優れた実装の1つは、Qtのシグナル/スロットシステムです。オブジェクトにはシグナルがあり、スロット(実際にはメソッド)をシグナルに接続できます。接続されたスロットは、信号が発信されたときに呼び出されます。

あなたの問題のいくつかは、あなたがあなたのオブジェクトのそれぞれに単一の通信運河を持っているという事実から生じているように私には思えます。これにより、すべてのメソッドにディスパッチメカニズムが必要にupdateなり、コードが非常に複雑になります。

Qtからインスピレーションを得て、メッセージや受信者の種類ごとに異なるシグナルを使用できます。シグナルのコードは次のようになります。

class Signal:
    def __init__(self):
        self.subs = []

    def subscribe(self, s):
        self.subs.append(s)

    def signal(self, *args, **kwargs):
        for s in self.subs:
            s(*args, **kwargs)

たとえば、GUIにはシグナルがstop_signalあり、スレッドにはそれを処理するメソッドがあります。

def handle_gui_stop(self):
    self.console_logger.debug("Facemovie is going to stop")
    self.my_logger.debug("Facemovie is going to stop")
    self.stop_process = True
    # ...

初期化コードのどこかで、すべてを結び付けます。

gui.stop_signal.subscribe(thread.handle_gui_stop)
于 2012-10-31T09:50:42.543 に答える
3

最近、同様のアーキテクチャ(GUIスレッド+別の作業スレッド)でGUIアプリを作成しましたが、最終的に2つのキュー(Queue Pythonモジュールから)の形式でスレッド間に明示的なプロトコルを作成しました。1つのキューは、GUIによって行われた要求用であり、ワーカースレッドによって消費されます。もう1つのキューは、ワーカースレッドによって生成され、GUIによって消費される回答用です。

スレッド間の通信が明示的である場合、更新がいつどこで行われるかを完全に制御できると、はるかに明確になります(GUIメソッドはGUIスレッドからのみ呼び出すことができます)。

サーバー環境でのこのモデルの自然な拡張は、AMQPのようなメッセージキュープロトコルです。

于 2012-11-04T19:49:59.170 に答える
2

アプリケーションスレッドは、GUIとアプリケーションAPIの間のコミュニケーターであるため、通信についてより明確にする必要があります。これは、GUIとアプリケーションAPIからのワーキングセット(キュー)を分離することで実現できます。また、アプリケーションスレッドは、コマンドの送信者と受信者を含む配信タイプのパターンを処理できる必要があります。これには、異なるキュー間の通信の管理が含まれます(たとえば、GUIキューには、アプリケーションAPIキュー内のコマンドを待機している保留中のコマンドがあります。これが完了すると、アプリケーションスレッドはキュー間で結果を返します)。そして、各キューはオブザーバーそのものです。

アプリケーションを拡張するという点では、将来的にGUIを追加したいと考えています。これは、上記の要求/応答(または送信者/受信者)パターンの実装によって処理されます(これで十分です)。

水平方向ではなく垂直方向にレイヤーを追加する場合は、同じアプリケーションスレッドを使用して新しいレイヤー間で上位に通信しないでくださいまあ、物理的には同じでもかまいませんが、実質的には少なくとも異なっている必要があります。これは、上記で説明した内容(個別のキュー)を正確に実装することで実現できます。動的に追加するキューを導入することにより、新しいレイヤーを追加する可能性が開かれます(新しいレイヤーは単に新しいキューに対応します)。

于 2012-11-06T23:10:49.657 に答える
0

特にGUIの場合は、別のパターンであるMVCをお勧めします。オブザーバーパターンが含まれており、オブザーバーのみよりも堅牢です。

懸念事項を分離するため、懸念事項が解決されます。各レイヤーには非常に特定の役割があり、それらの間のインターフェイスを変更しない限り、任意のレイヤーを変更できます。

于 2012-11-06T12:34:38.597 に答える