1

Let's imagine you have a fullscreen C++ desktop application that consists of several screens with each of them having a distinct function and a ViewController with appropriate models as well. For example a set of the following very simplified screens:

  1. Quiz: The user is navigated through a set of multiple-choice questions.
  2. Quiz Results with Statistics.
  3. Information: The user is presented with information about a specific subject.
  4. Menu (Quiz, Information, Exit)

Judging by the GRASP principle Information Expert, each ViewController will know best when it is finished and time to move to a new screen. Yet by the same principle, it is not the right place to decide what the next screen should actually be. In this rather simple example, one could argue it would be okay but in a more complex application, it will undoubtedly lead to duplicated code and logic as well as higher coupling and lower cohesion. There is also the problem that you would have to create the new widget and controller within the current screen's ViewController which brings all sorts of new problems and at least by the Creator principle, it is not the right choice. You would have to introduce a Factory to alleviate some of the problems, amongst other things.

So, the next logical step is to introduce an ApplicationController with the sole responsibility of managing Views and their controllers including the navigation flow from one view to the next.

This still leaves one problem wide open in my opinion: How to signal the ApplicationController that it is time to move to a different screen and hand over the control to that object properly?

One could use the Observer pattern, for example. Yet what if you have an expensive View active at the moment and want that one destroyed once the new screen is active? If the current ViewController signals the ApplicationController that the next screen should go up, it can manage everything up to the point where it would destroy the currently active screen which it cannot do because the current call comes from exactly that object. Apart from several other problems with that approach.

So my question is (and sorry for all the verbose introduction :P): How do you properly implement a navigation flow from one fullscreen widget to a different one with MVC which solves the above problems, splits the responsibility between the View- and ApplicationController and is nicely object oriented in terms of coupling and cohesion?

4

1 に答える 1

0

時々、思考プロセスの1つの詳細を見逃し、自分が犯した間違いに気付かずに、問題の可能性をすべて広げてしまうことがあります。

この場合の詳細は、非同期イベントと同期イベントを自然に投稿できることでした。イベント投稿メソッドのコンテキストにいないことを確認する必要がある場合は、非同期イベントを投稿します。ハンドラーでそのイベントを受信すると、コンテキストが残されたことを確認できます。たとえば、必要に応じて、オブジェクトを安全に削除できます。当然、イベントハンドラーは、削除しようとしているのと同じオブジェクトのコンテキスト内にあるべきではありません。

完全を期すために:Qtでは、connect()を使用して作成する信号/スロット接続ごとに、タイプがQt::QueuedConnectionであることを指定できます。シグナルを発生させると、コントロールがスレッドのイベントループに戻るまでシグナルは配信されません。通常、Qt :: AutoConnectionが使用され、レシーバーが同じスレッドにある場合は発生時にシグナルを配信し(Qt :: DirectConnection)、レシーバーがにある場合はそのシグナルのキューイングにフォールバックします(Qt :: QueuedConnection)。別のスレッド。

wxWidgetsでは、たとえばアプリケーションシングルトンから利用できるwxEvtHandler :: QueueEvent(wxEvent * event)を使用してイベントをキューに入れることができます。

于 2012-05-29T13:51:44.840 に答える