24

私たちは本当に便利だと思うシグナルとスロットを提供する Qt を使用しています。ただし、大きな力には大きな責任が伴います。この機能を誤用するのは非常に簡単だと思います。

シグナルスロットの使用に関するベストプラクティスはありますか? この方法でいくつかの一般的なガイドラインを見つけるのに苦労しています。いくつかの質問 (私は明確な意見を持っていますが、私のチームのすべてのメンバーが同意しているわけではありません):

  • シグナルを使用してエラーを報告しても問題ありませんか?
  • シグナルが処理されると仮定してもよろしいですか?
  • アクションを開始するためにシグナルを使用できますか? たとえばsignal displayInfoScreen()、情報画面を表示するスロットで処理する必要があります。

シグナルを使用すべき/すべきでない場合についてのその他の意見は歓迎です!

4

5 に答える 5

14

オブジェクトを分離するため、シグナルとスロットは強力です。以前に回答したように、信号にスロットが接続されていると想定することはできません。

信号/スロット ベースの設計の主な欠点は、オブジェクトの 1 つのアクションが、送信された信号に接続された他のオブジェクトの他のアクションをトリガーできるため、実装したロジックを非常に簡単に追跡できることです。望ましくない副作用、再帰呼び出しなどが発生しやすくなります。

于 2010-02-24T12:51:46.740 に答える
13

シグナルを使用して
エラーを報告しても問題ありませんか?

はい、たとえば、完了信号がステータスを運ぶ QFtp を参照してください。エラーが発生したという情報だけで、実際のエラーは含まれません。

シグナルが処理されると仮定してもよろしいですか?

いいえ。送信者は、特定のアプリケーションがそれに依存する可能性があると想定することはできません。たとえば、File - New を表す QAction は、アプリケーションが機能するために処理する必要がありますが、QAction オブジェクトはそれほど気にしません。

アクションを開始するためにシグナルを使用できますか? たとえば、シグナル displayInfoScreen() は、情報画面を表示するスロットで処理する必要があります。

繰り返しますが、たとえば QAction オブジェクトです。ただし、コンポーネントを再利用できるようにする場合は、実際のクラスがコンポーネントに依存しないように注意する必要があります。

于 2010-02-24T16:42:33.627 に答える
11

信号が処理されると想定しても大丈夫ですか?

いいえ、ちがいます。信号はファイアアンドフォーゲットタイプのものです。誰が信号に接続し、それが何をするかは、エミッターの関心事ではありません。

于 2010-02-24T10:29:22.963 に答える
6

シグナルを使用してエラーを報告しても問題ありませんか?

はい、しかし私は一般的にこれを状況依存にします。エラーが非同期で発生する可能性がある場合は、それを示すシグナルが適切です。クライアントコードが特定の関数を呼び出したときにのみエラーが発生する場合、エラーはシグナルとしてではなく、その関数からの応答にあるはずです。ただし、その間にはさまざまな状況があり、ケースバイケースで行われる可能性があります。

また、シグナル スロット メカニズムはクロススレッド通信を容易にすることができます (これは非同期の場合と見なされる可能性があります)。

シグナルが処理されると仮定してもよろしいですか?

信号は (哲学的に) 何かが起こったことを示すように設計されています。他の人が指摘しているように、信号がスロットと一致すると仮定することは決して良い考えではありません。

アクションを開始するためにシグナルを使用できますか? たとえば、シグナル displayInfoScreen() は、情報画面を表示するスロットで処理する必要があります。

シグナルはアクションを開始するために使用できますが、おそらくあなたが考えている方法ではありません。このシグナルは、fooが発生したことを示します。クラスを監視しているコードが、 fooが発生したときにダイアログを表示する必要があると判断した場合、そのアクションを開始するためにシグナルが使用されました。ただし、通常、適切なアクションが発生することを保証することは、シグナルを発行するクラスの責任ではありません。そのアクションを実行する責任がないためです。(そうであれば、それは同じクラスの一部である必要があり、シグナルは必要ありません。)

于 2010-02-24T16:33:48.953 に答える
4

シグナル/スロット(イベントとも呼ばれます)は、オブジェクト間の結合を取り除くための良い方法です。

たとえば、モデルがどのように機能するかを理解するビューを持つ代わりに、モデルが変更されると、モデルを「リッスン」します。モデルは、それがいつ変わるか、何が変わるかを言う責任があります。

イベントの問題は、クライアントの要件を使用してイベントを設計する場合です。たとえば、シグナルdisplayInfoScreenはこのシグナルを使用するオブジェクトについて何かを想定しているため、シグナルを使用しないでください。代わりに、そうあるべきでinfoChangedあり、InfoScreenDisplayerこの信号をリッスンして画面に表示します。必要に応じて、InfoTweeterPosterツイーターが変更されるたびに情報を投稿するを後で追加できます。

于 2010-02-24T10:29:58.790 に答える