2011-11-17 36 views
1

我有一個視圖,控制器和模型。這是一個桌面應用程序,讓它說是一個瀏覽器。所以,有一個名爲AppCurrentStatus的對象。其中包含窗口位置,打開多少個窗口以及窗口內容。哪種設計更好?單個對象或每次傳遞一個對象?

所以,我們說,用戶想打開一個新標籤,然後流程是這樣工作的:

1. View (user interface) press new a tab. 
2. Fire event to controller. 
3. Controller update the AppCurrentStatus, add one new tab. 
4. Controller notify the model, the model store the data, just in case the user close the browser incidentally 

問題是,視圖,控制器和模型是如何得到這些信息,他們從AppCurrentStatus需要?我應該讓AppCurrentStatus成爲一個單身人士,讓每個人都可以稱之爲單身人士。例如,用戶可以有3個以上的選項卡,控制器可以通過單例直接調用它,以檢查它是否有3個選項卡。如果成功添加新選項卡,模型是否可以保存AppCurrentStatus並詢問控制器,只需從單例中調用它即可。

另一種方法是將AppCurrentStatus作爲變量保存在控制器中,當用戶添加一個新選項卡時,事件將觸發並告訴控制器檢查自己的AppCurrentStatus,如果修改,只需將此對象傳遞給模型,保存。

更多指定告訴不同,該模型會喜歡這個,辦法之一:

-(void)save(); //calling singleton 

如果方法有兩個是這樣

-(void)save(AppCurrentStatus aAppCurrentStatus); //save from a object 

或其他更好的解決方案可以建議?

回答

0

這個問題混淆了兩個不同的概念:單身人士靜態等級

使用靜態類將起作用 - 所有狀態數據都是靜態存儲的,並且可以從任何地方訪問。既然你的問題也強調面向對象的原則,但我會建議這不是最受歡迎的方法,因爲它會限制你的未來發展。靜態類不適合依賴注入或被模擬或裝飾。

單例實現經常被忽視,但爲您的案例提供了一個很好的解決方案 - 在您繞過變量時它是兩全其美的,但它們都指向相同的單個對象。這樣,如果你想創建單元測試,你仍然可以使用裝飾器或模擬組件,但是所有控制器最終引用並訪問相同的狀態信息。

2

我發現我經常用單身人士開始我的代碼。儘管我知道的更好 - 像這樣的單身人士基本上是全局的,我們都知道全局人士是不好的。

但是,它是這樣的容易代碼這樣的單身人士,並在必要時使用它。

通常,在一段時間 - 一個月左右 - 我最終切換到「傳遞」模式。通常因爲最初作爲一個單身人士而成爲不止一個人。例如。在我爲謀生而做的東西中,singleton processor_under_test()變成了多個處理器。

就你而言,問問自己:AppCurrentStatus中反映的單個應用程序最終會成爲多個協作應用程序中的一個的可能性有多大?如果低,單身人士可能是簡單的方法。

(在相關的靜脈,想想許多單個文檔的應用程序如何成爲多個文件。)

不要擔心自己這一點,關於尋找最好的方式。像這樣的變化只是編程的一部分。有時候,你從單身人流到了,我們可以稱之爲N噸。有時候回來。

但是,這裏值得一提的是兩個相關的模式。

首先,當作爲一個singleton出現的是一個N-ary-ton時,你不需要立即放棄使用全局單例的易用性。相反,你可以創建一個主單體,我通常稱之爲「environ」,它包含幾個N-ary-ton對象或引用,以及其他可能的東西。另外,如果您選擇傳遞對象,則不一定只需傳遞AppCurrentStatus即可。因爲您最終可能最終還需要傳遞其他內容。再次,我通常傳遞一些我稱之爲環境的東西,而在不同的呼叫點可能有不同的形狀。


最後兩個注意事項:

(1)我願意忍受使用在應用程序代碼的單身不是重用一個很好的候選人。但是,我發現如果我正在編寫可能想要包含在庫中並在其他地方重用的代碼,那麼取決於單例是不好的 - 因爲其他地方可能不希望與您的單例混淆在一起, 。

同樣,由於某種原因,我發現很難爲單例代碼編寫好的單元測試。我現在不記得所有的細節,但是,考慮一下:你如何測試構建和破壞單例的幾種不同方式?如果沒有其他原因而不是應用程序關閉,您可能需要析構函數或終結器。

基於這些原因,我經常會創建兩個類:

內部類,它在你的例子我可以稱之爲AppCurrentStatus。 和外部類AppCurrentStatus_singleton。

可能隱藏將使用單例的人的內部類的實現,但暴露它,以便您可以編寫一套很好的單元測試。我經常這樣做,以至於在C++中我創建了一些模板來完成簡單的例子:Singleton。 (2)最後,如果你關心性能,傳遞的參數越多,速度越慢。而單身全球可能更快。

對於大多數程序,這可能是一個不關心,過早的優化。我只是想想那樣的事情,因爲表演是我的麪包和黃油。

相關,可維護性:雖然singletons是全局變量,全局變量是不好的,但我認爲函數/方法的大參數列表更糟糕。我寧願使用單身。但是參數對象desiogn模式可能會更好。


好吧,我撒謊:另一個問題是贊成單身人士:有時候你沒有能力去改變所有的代碼。例如。有時你會將回調傳遞給某個庫,最終會調用你的代碼。您可能沒有向該界面添加參數的選項。一個單身人士可以做到這一點。

相關:任何做回調的人都應該提供一個逃生方法:一個通用對象引用或者cookie,回調操縱庫傳遞,但不會將語義推理到。

0

我建議您使用工廠方法來獲取AppCurrentStatus值的實例,並在每次需要訪問它時調用它。

AppCurrentStatusHolder.getAppCurrentStatus() 

現在在開始您可以使用單例,但如果您稍後需要更改策略,那麼您不太需要實施。

相關問題