2013-05-13 34 views
22

比方說,我們有以下類別:視圖應該保存模型引用嗎?

查看

@interface ArticleView : UIView 
@property IBOutlet UILabel *titleLabel; 
@property IBOutlet UILabel *bodyLabel; 
@end 

型號

@interface Article : NSObject 
@property NSString *title; 
@property NSString *body; 
@end 

控制器

@interface ArticleViewController : UIViewController 
@property Article *myArticle; 
@property ArticleView *myArticleView; 
- (void)displayArticle; 
@end 

@implementation 
- (void)displayArticle { 
    // OPTION 1 
    myArticleView.titleLabel.text = myArticle.title; 
    myArticleView.bodyLabel.text = myArticle.body;  

    // ... or ... 

    // OPTION 2 
    myArticleView.article = myArticle; 
} 
@end 

OPTION 1

  • PRO:兩者視圖和模型不連接到彼此。
  • CON:控制器需要知道,這兩個模型和視圖的細節。

OPTION 2

  • PRO:控制器代碼輕且柔性的(如果視圖或模型改變,則控制器代碼保持相同
  • CON:的視圖和模型是耦合的,因此可重用性較差

在選項2中,A rticleView將不得不改變,以保持對模型的引用:

@interface ArticleView : UIView 
@property IBOutlet UILabel *titleLabel; 
@property IBOutlet UILabel *bodyLabel; 
@property Article *article; 
@end 

文章二傳手然後可以覆蓋相應地更新視圖,就像這樣:

- (void)setArticle:(Article *)newArticle { 
    _article = newArticle; 
    self.titleLabel.text = _article.title; 
    self.bodyLabel.text = _article.body; 
} 

所以我的問題是,這在OO和iOS/MVC最佳實踐方面,這兩個選項中的哪一個最好?

我當然看到這兩個被使用。我在UITableViewCell子類中見過OPTION 2。

我也讀了視圖和模型的設計應是可重複使用的,而不是依靠什麼而視圖控制器是爲了是最可重複使用的一羣。

我的直覺是使用選項1,只是因爲我寧願視圖控制器做結合的模式,認爲骯髒的工作,讓模型和視圖保持獨立,不知道對方。但是,由於一些觀點只是爲了做一件事而設計的,所以將它們直接綁定到特定的模型可能並不是那麼糟糕。

我很想聽聽你對這個意見。

+0

選項2更好。因爲視圖和模式似乎在那裏有特定的工作,不需要重複使用。所以你不應該在管理員課上做他所有的混亂工作。使其靈活輕便。 – Divyu 2013-05-13 07:14:39

+1

選項1是更好的設計。但我更經常地使用選項2,因爲#1它更容易,#2更少(重複)代碼,#3我不認爲我會在其他地方重複使用這個類 – 2013-05-13 07:14:58

+1

根據我的經驗,帶有模型引用的視圖是*大量*痛苦的屁股調試/理解。當我回到使用它們的舊代碼時,需要很長時間才能確定到底發生了什麼。 – sapi 2013-05-13 07:15:00

回答

29

這並不總是一個或者或者決定。你的第一個選擇更典型的是Apple的MVC版本;在iOS中,模型和視圖通常不是直接相互對話,而是控制器完成大部分的協調。然而,擁有一個知道更大模型中特定類的自定義視圖並不是不合理的。您可能會有一個知道如何處理文章的ArticleView,但ArticleView應該仍然會收到它從控制器顯示的任何文章,而不是直接從較大的模型中獲取文章。

MVC的目標之一是使模型和視圖類更加可重用。如果你保持你的ArticleView非常簡單,那麼控制器必須完成所有解釋文章的工作,那麼你實際上可能會失去可重用性 - 每次你想用一個新的視圖控制器重用ArticleView時,你必須重現所有解釋ArticleView文章的代碼。或者,您始終使用相同的視圖控制器類來管理ArticleView。這些都不是「可重複使用的」。

與此同時,您必須承認,ArticleView和ArticleView之間存在某種自然耦合,因爲ArticleView旨在顯示文章的所有相關詳細信息,無論它是直接從文章中獲取它們或者由視圖控制器設置它們。如果文章發生變化,ArticleView將不得不改變是否知道文章的可能性很大。

因此,儘管文章可能是一個模型類,但可以有一個知道它的視圖是可以的。你不想要的是一個ArticleView,它知道更大的模型,並試圖從模型本身獲取文章。這將您可以在ArticleView中顯示的文章限制爲僅在ArticleView看起來可以找到的那些文章 - 它會阻止您顯示其他來源的文章。

+1

很好想過。 @Caleb有釘。 – aLevelOfIndirection 2013-05-13 07:44:43

+1

我同意一個可重用模型,但是您創建了多少次可重用視圖?不能很多,當然? – PeteH 2013-05-13 07:47:01

+0

@PeterH即使在單個應用程序的上下文中,可重用性也有所不同。例如,OP的應用程序的第2版可能會添加創建新文章的功能,或者可能會存儲一組最喜歡的文章。知道如何使用高於數據的字符串和數字填充自己的視圖可以真正簡化事情。 – Caleb 2013-05-13 13:15:11

-1

選項1是MVC。選項2不是。

OO是在不同的級別真的,你有一個模型對象,視圖和控制器,所以你不能做更多的是面向對象的。

這兩個選項當然可以工作,但MVC的存在是有原因的(我相信你已經完成了一些常規閱讀like this),你會發現如果你的代碼更易於閱讀,理解和重用遵循MVC的原則。

+1

您是否閱讀過該鏈接?架構圖顯示模型和視圖之間的耦合。首先介紹MVC作爲概念的JOT文章描述了模型和視圖之間的耦合。 MVC上的Apple文檔聲明「視圖對象通常與MVC應用程序中的模型對象分離」,這很難斷言MVC按照定義在模型和視圖之間解耦。聲明「選項1是MVC。選項2不是」。是完全沒有根據的。 – 2016-05-29 19:08:07

1

坦率地說,有時我自己做選項2。但選項1「不在書中」。

2

是的,你已經證明了這個問題的理解。

選項1是MVC的經典結構,我推薦它作爲你提供的兩個默認路由。

僅僅因爲選項1是一個更純的定義,並不意味着它需要應用於任何可能的地方。

我做出的最常見的偏差是當一個實現是如此特定並且沒有重用時,引入一個專用的控制器類型只會導致更多的代碼來編寫和維護實現很小,非常專業化,不可重用,並且不會大幅增長。如果程序很適合將V和C摺疊成一個單獨的實現並適合某些小的代碼(例如幾十行代碼),我不擔心使用選項2.

現實比但是要點是:不要覺得你需要堅持#1,儘管你可能不會理解在2年前編寫和維護一些中等規模的程序之前,如何使用#2可以引入維護問題。從一個到另一個可以在一個已發貨的程序中引入許多變化 - 本來可以避免的。

選項2的使用應該是少數。如有疑問,請使用選項1。

無論哪種方式,我相信模型不應該知道視圖或控制器。

對我來說,在編寫可重複使用的組件時,嚴格遵守更重要。

+1

+1表示M不應該知道V或C.M可能是可重複使用的,V和C的可能性更小 – PeteH 2013-05-13 07:46:07

0

正如其他人所說,選項1是更純粹的方法。控制器應該是視圖和模型之間的「接線盒」。

然而,這種類型的方法(例如微軟稱爲MVC的框架)的一些實現豐富了選項2.當然,在微軟的情況下,View和Model相互瞭解的事實允許IDE創建大量的樣板代碼,併爲您節省「麻煩」。這樣做的好處是你花時間寫「功能」代碼而不是「接線」代碼。所以,純粹與否,你可以欣賞他們來自哪裏。

正如軟件開發中經常發生的那樣,選項1和選項2之間的選擇歸結爲純粹性與實用性。

1

在蘋果公司關於這個主題的官方指導方面,在Objective-C編程的概念的MVC as a Compound Design Pattern部分文件討論了這兩種方法,但清楚地闡明瞭蘋果的選項1的優先級高於你的選擇2.實際上Cocoa Core Competencies只列出了選項1.

我從來沒有後悔實施選項1的方法,但是當我偷工減料並且試圖讓模型和視圖直接交互時,我經常後悔當我不得不去在稍後的日期返回並修改系統。

+0

感謝您分享您的經驗。通常,大型項目的個人經驗比文檔更有價值。 – nebs 2013-05-13 18:04:53

相關問題