2013-01-10 84 views
3

剛剛開始學習Objective-C和可可在BNR的幫助下可可編程Mac OS X(第4版),我正在研究一個基於文檔的應用程序。我已經通過在文檔架構蘋果的開發者文檔閱讀,並且選擇了繼承NSWindowController和我NSDocument子類中重寫makeWindowControllers。我有這樣幾個原因:從視圖邏輯Cocoa MVC:「模型控制器」和「視圖控制器」之間的交互

  • 到單獨的模型邏輯(在NSDocument子類)(在NSWindowController子類)。
  • 定製的我的文檔窗口(蘋果開發者文檔中說,這樣做沒有不必要的副作用的正確方法是繼承NSWindowController和覆蓋windowTitleForDocumentDisplayName:
  • 蘋果的文檔似乎強烈建議繼承NSWindowController爲所有,但最簡單的標題應用程序,而我絕對不是「簡單」

所以,我NSDocument子類是模控制器,我NSWindowController子類是視圖控制器。此外,我明白應用程序的大部分「工作」都是在控制器對象中完成的,因爲視圖和模型應該儘可能不受應用程序和可重用的影響。現在我的問題是:這兩種類型的控制器如何相互作用來實現這個「工作」?

例如,假設我正在寫一個電子表格應用程序,我想有一個菜單項(或工具欄按鈕),帶來了創造一些我的數據的圖表或圖形的紙張。在該表中,用戶將輸入用於創建圖表或圖表的各種參數和選項,然後單擊「確定」(或任何按鈕被調用)。

誰應該菜單項的行動作出迴應,該文件(模型控制器)或窗口控制器(視圖控制器)?實際加載和顯示工作表的任務似乎是「與視圖有關」,因此它應該放在窗口控制器中,對嗎?但是工作表的控制器需要一個模型來顯示給用戶(一個Chart對象,或者ChartInputs);該模型在哪裏創建並提供給圖紙控制器?應的文件,以通過創建ChartInputs模型對象的菜單項作出響應,然後傳遞到窗口控制器,它創建片控制器,向它傳遞模型對象,並且示出了片材?或者,如果窗口控制器響應菜單項,請求一個新的模型對象(可能通過某種工廠通過依賴注入提供給窗口控制器的構造函數),然後繼續創建工作表控制器,傳遞模型並顯示錶單?

怎麼樣的用戶填寫後的薄片,並點擊「OK」?應該在哪裏控制返回來處理用戶的選擇並實際創建圖表 - 窗口控制器,文檔還是兩者?在單擊「確定」之後,但在表單被解除之前(如果某些內容無效),驗證用戶輸入的邏輯如何?

回答

6

首先,考慮你的NSDocument的窗戶操作。例如,您可以創建一個共享您的NSDocument類的實用程序應用程序,爲腳本,打印或其他操作打開文檔,但不顯示主文檔窗口。想象一下你的NSDocument類可以重用那個應用程序 - 並且把你不想要的邏輯放到你的窗口控制器中。這樣,NSDocument子類主要負責影響文檔狀態的活動。

這些都是模型的控制器的(NSDocument子類)職責:

  • 序列化和反序列化
  • 加載和保存
  • 操縱文檔的狀態
  • 管理和調度打印意見
  • 監視文檔以查看其他人的更改
  • 刷新支持d ATA源 - 這影響文檔模型源 - 以及將更改應用到模型和文檔根據需要
  • 管理與文檔相關的
  • 擁有撤消管理
  • 揭露的基本模型中的活動日誌對象添加到視圖控制器
  • 創建窗口控制器
  • 促進一些編輯行爲,如改變到一個屬性觸發對象的創建或移除

如果您使用的是核心數據,則託管對象上下文,持久存儲協調器和持久存儲是模型控制器的一部分,而不是模型。當然,託管對象本身也是模型的一部分。

這使得這些責任到模型:

  • 用於插入,重排,並且刪除模型輔助方法對象
  • 用於訪問模型
  • 數據驗證
  • 渲染的特定部分的輔助方法字符串模型,以各種格式
  • 序列化和反序列化自己
  • 促進一些編輯行爲,如改變到一個屬性觸發改變其它性質

在另一邊,這些都是視圖 - 控制器的職責:

  • 操縱視圖,以保持它在與模型
  • 操縱到與文檔狀態
  • 保持同步響應局部的動作,例如一個按鈕,用於添加或刪除一個對象模型視圖同步
  • 在這些視圖中顯示輔助視圖和響應輸入
  • 調度受UI中的選擇影響的操作,例如表視圖中的選定行
  • 管理編輯過程中使用的與控制器無關的輔助控制器如果您使用可可綁定,您的綁定也認爲控制器的一部分文檔本身(如Web服務數據)
  • 充當視圖的數據源對象

該設計對視圖控制器和模型控制器之間的職責進行了合理的分離。然而,他們都在坐在視圖和模型之間。雖然這產生模塊化,但不會產生去耦。

雖然我確實考慮過無窗操作,但我很大程度上是通過將相似的代碼放在一起,並分離感覺不合適的代碼,從而基本上實現了這種設計模式。我很好奇,如果其他人張貼權威的來源或參考文件,同意或不同意如何做到這一點。


拿起你的榜樣,我建議這種設計:

  1. EditorWindowController創建ChartParameters對象,並將其提供給文檔的模型的引用:

    [[ChartParameters alloc] initWithWorkbook:self.document.workbook] 
    
  2. EditorWindowController設置新圖表視圖,該視圖可能具有自己的NewChartViewController。它將ChartParameters和文檔對象傳遞給NewChartViewController並顯示窗口。

  3. ChartParameters對象負責驗證用戶的選擇。NewChartViewController需要操作視圖以使其與驗證結果保持同步。 (避免讓用戶犯了一個錯誤:不要等到最終驗證輸入)

  4. 當視圖完成時,NewChartViewController詢問模型使用給定的參數來創建一個新的圖表:

    [self.document.workbook addChartWithParameters:self.chartParameters] 
    

如果你想在尚未-A-圖表對象是文檔的一部分,你能做的就是這種方式來代替:

  1. EditorWindowController問文檔的T型車o創建一個新的圖表對象:

    Chart *newChart = [self.document.workbook addChart] 
    
  2. Thew新圖表應設置一個標誌,表明它沒有準備好顯示。

  3. EditorWindowController設置NewChartViewController,將它傳遞給圖表,顯示窗口。

  4. 圖表對象驗證用戶的選擇,NewChartViewController保持視圖同步。

  5. 完成後,告訴圖表它已準備好顯示。或者如果用戶取消,請將其刪除。

在任一這些設計中,NewChartViewController是一個模型的控制器和視圖 - 控制器在一個,本地化爲它的特定任務。