2012-05-27 49 views
1

讓我們假設您有一個全屏C++桌面應用程序,它由幾個屏幕組成,每個屏幕都有一個獨特的功能和一個具有合適模型的ViewController。例如一組以下非常簡化的屏幕:在C++桌面應用程序的上下文中導航/查看MVC的流程

  1. 測驗:用戶通過一組多選題進行導航。
  2. 測驗結果與統計。
  3. 信息:向用戶呈現關於特定主題的信息。
  4. 菜單(測驗,信息,退出)

由GRASP原則信息專家來看,每個視圖控制器將最知道什麼時候完成,時間移動到一個新的屏幕。然而,按照同樣的原則,它不是決定下一個屏幕實際應用的正確位置。在這個相當簡單的例子中,人們可能會認爲它會好,但在更復雜的應用程序中,它無疑會導致代碼和邏輯重複以及更高的耦合度和更低的內聚力。還有一個問題是,你將不得不在當前屏幕的ViewController中創建新的小部件和控制器,這會帶來各種新問題,至少在原理上是這樣,這不是正確的選擇。除了其他方面,你將不得不引入工廠來緩解一些問題。

因此,下一個合乎邏輯的步驟是引入一個ApplicationController,它唯一負責管理視圖及其控制器,包括從一個視圖到另一個視圖的導航流。

這仍然給我留下了一個問題:如何向ApplicationController發出信號,指出是時候移動到另一個屏幕並將控件正確地移交給該對象?例如,人們可以使用觀察者模式。然而,如果你現在有一個昂貴的查看活動,並希望在新的屏幕激活後銷燬該活動?如果當前的ViewController通知ApplicationController下一個屏幕應該上升,那麼它可以管理所有事情,直到它將銷燬當前活動的屏幕,因爲當前的調用正好來自該對象。除了這種方法的其他幾個問題。

所以我的問題是(並對所有的詳細介紹:P抱歉):如何正確實現從一個全屏窗口小部件到不同的MVC解決上述問題的導航流,拆分視圖之間的責任 - 和ApplicationController並且在耦合和內聚方面很好地面向對象?

+0

愚蠢的我,我沒有注意到我登錄在serverfault。 :(對不起,有人可以將問題轉移到適當的網站嗎?非常感謝。 – khaos

回答

0

有時你會錯過思維過程中的一個細節,並且你甚至沒有意識到自己犯的錯誤,就會打開一大堆問題。

在這種情況下,細節是您可以自然發佈異步事件和同步事件。如果您必須確保您不再處於事件發佈方法的上下文中,請發佈異步事件。一旦您在處理程序中收到該事件,就可以確定該上下文已保留。例如,如果您願意,您可以安全地刪除該對象。自然,事件處理程序不應位於您要刪除的同一對象的上下文中。

爲了完整:在Qt中,您可以爲connect()指定的每個信號/插槽連接指定它應該是Qt :: QueuedConnection類型。如果你提出一個信號,它將不會被傳遞,直到控制回到線程的事件循環。通常情況下,使用Qt :: AutoConnection,如果接收器在同一個線程中,或者如果接收器處於插入狀態時又退回到排隊該信號(Qt :: QueuedConnection),則在使用Qt :: DirectConnection時它會發出信號一個不同的線程。

在wxWidgets中,您可以使用wxEvtHandler :: QueueEvent(wxEvent *事件)對事件進行排隊,例如可以通過應用程序單例程來使用該事件。