2011-09-24 79 views
1

爲iOS開發了一段時間之後,我已經習慣了這門語言,並試圖在設計結構良好的應用程序方面做得更好。最初我的工作重點是看到某些功能,所以我最終用巨大的視圖控制器進行了可怕的設計。現在,我正在學習分離我的模型類,並試圖讓我的架構更加模塊化。我非常感謝以下示例情況的任何建議:認證的可可設計模式

我正在開發一個應用程序(其中包括)從服務器中提取文章列表並顯示它們。但是,用戶必須經過身份驗證才能檢索此列表。由於應用程序的其他方面使用相同的身份驗證,我希望單個類來管理身份驗證。目標是當任何控制器從要求認證的模型請求數據時,如果用戶未通過認證,認證提示將自動呈現。

我希望創建如下:

VIEW
- ArticlesView
- AuthenticationView

控制器
- ArticlesViewController
- AuthenticationViewController
- ArticleManager(單)
- 的AuthenticationProvider(單)

模型
- 文章

當應用程序首次加載,執行將達到ArticlesViewController的viewDidLoad方法。在這種方法中,我得到了一個ArticleManager的共享實例,指定認證類爲認證提供者,並要求它提供最近的文章列表。

// ArticlesViewController.m 
-(void) viewDidLoad { 
    ... 
    AuthenticationProvider *authProvider = [AuthenticationProvider sharedInstance]; 
    [[ArticleManager sharedInstance] setAuthenticationProvider:authProvider]; 
    [[ArticleManager sharedInstance] fetchNewArticles]; 
} 

如果沒有認證是必要的,在ArticleManager將成功地從服務器檢索列表,並張貼通知,告知有興趣的人知道,這些條款已檢索。該ArticlesViewController處理這個通知:

// ArticlesViewController.m 
- (void) handleNewArticlesNotification:(NSNotification *)note { 
    [self updateUI]; 
} 

然而,如果需要身份驗證,用戶需要有登錄屏幕前的文章可以獲取和顯示。所以我想象ArticleManager做這樣的事情:

// ArticleManager.m 
- (void) fetchNewArticles { 
    if([self.authenticationProvider isAuthenticated]){ 
     // go fetch list from the web 
    } 
    else { 
     [self.authenticationProvider presentAuthenticationRequest]; 
    } 
} 

現在,在這一點上,我遇到了一些困難,充實的細節剩餘部分。 AuthenticationProvider可以將AuthenticationViewController作爲AppDelegate的窗口的rootViewController中的模式視圖控制器提供,AuthenticationProvider將作爲AuthenticationViewController的委託。 AuthenticationViewController可能會愚蠢到它正在採取的實際操作,並且它會委託(AuthenticationProvider)執行驗證用戶的工作。一旦用戶通過身份驗證,AuthenticationProvider會關閉模式視圖控制器(AuthenticationViewController)。

但ArticleManager如何得到通知,它請求的身份驗證已完成?它需要能夠分別處理成功和失敗的認證嘗試。成功的身份驗證最終會導致再次調用fetchNewArticles。

一個想法是讓ArticleManager成爲AuthenticationProvider的委託。這似乎適用於這種情況,但還有其他模型管理器也可能依賴於AuthenticationProvider。如果AuthenticationProvider不是單身人士,推測這將被解決。這是一個體面的設計方法嗎?

感謝您花時間幫助我理解一個好的設計方法。我已經編碼了幾次,但總是陷入困境。另外,如果整個方法需要重新設計,請隨時指向另一個方向。

非常感謝!

回答

1

我一直使用Global NSNotifications在用戶登錄或註銷時發佈。每個呈現不同數據的視圖控制器都可以訂閱這些通知,並在發生事件時相應地進行更新。

這很好,因爲您可能已經有其他視圖(可能在其他選項卡中)已經加載,並且在用戶登錄或註銷時需要刷新。

+0

謝謝,布拉德。我看到那裏的好處。在我的情況下,我想我會讓文章管理器響應登錄通知。然後,它可以在獲取數據並通知其委託(ArticlesViewController)時進行另一次傳遞。 – jmac

0

一個想法是讓ArticleManager成爲 AuthenticationProvider的代表。這似乎適用於這種情況,但其他模型管理器也可能依賴於AuthenticationProvider。 推測如果AuthenticationProvider不是 單身人士,這將被解決。這是一個體面的設計方法嗎?

也許相反,您可以讓AuthenticationProvider單例提供AuthenticationSession對象,將調用者設置爲AuthenticationSession的委託,並要求AuthenticationSession執行身份驗證。

+0

謝謝,丹拉。你介意在你的回答中詳細解釋一下嗎?這與AuthenticationProvider執行身份驗證本身有什麼不同?也許如果你明確描述使用ArticleManager,我會更好地遵循。 – jmac

+0

您可以在AuthenticationProvider中擁有身份驗證信息,該身份驗證信息可以保持爲單例(只有一個狀態,您可以進行身份​​驗證或不驗證...),並且AuthenticationSession將用作您的AuthenticationProvider代理。這是屬於呼叫者的座席,因此您可以將呼叫者設置爲代表。 – Danra