iOS開發設計模式-MVC

一、MVC的概念

MVC是Model-VIew-Controller,就是模型視圖控制器 

MVC把軟件系統分爲三個部分:Model,View,Controller。在cocoa中,你的程序中的每一個object(對象)都將明顯地僅屬於這三部分中的一個,而完全不屬於另外兩個。


Model = 你的程序是什麼(而不是你的程序是如何顯示的)

舉個簡單的例子.比如微信的打飛機,Model就是:你的小飛機的子彈攻擊力是多少?你的小飛機上裝的是什麼武器,單線子彈,雙線子彈,你的小飛機還有多少導彈?等等。再概括點說,就是你的程序將要實現的功能,或者是它所能幹的事情。


Controller = 如何使你的模型呈現給用戶(程序邏輯)

ontroller是程序內部的邏輯,大多情況下你將看不到它,它將Model和View捆綁在一起,它將處理用戶的輸入,例如,你按導彈的鍵子,Controller就會通過內部的邏輯來處理你的要求,並在屏幕上做出相應的顯示,你將看到整個屏幕上的小飛機爆炸。這也是Controller控制View的顯示的例子。所以你可以把Controller看成是連接M和V的橋樑。


View = 在屏幕上你所看到的(是你的Controller的“奴才”)


接着前面的小飛機,View就是:你的小飛機是什麼樣子的;還有,你的飛機在屏幕上的位置等等。總之,你在屏幕上看到的組件都可以歸類爲View。

MVC可以幫助確保幫助實現程序最大程度的可重用性。各MVC元素彼此獨立運作,通過分開這些元素,可以構建可維護,可獨立更新的程序組建。


二、M V C之間的交流模式

我們把程序分成三個部分,但並不希望他們完全獨立,因爲那樣的話,我們的程序將毫無意義和功能而言。它們之間必然存在某種聯繫,使它們能有機的成爲一個整體來實現各種強大的功能。而這種聯繫就是我們提到的交流方式。我們來看看下面的圖,此圖出自斯坦福大學CS193課程的課件。

           

圖中有幾條線把這三部分劃分開,有黃線,虛線,和白色的實線。我們把它們想象成路標。你可以看到,在M和V之間有兩條黃線,這表示什麼呢?它意味着你不能穿越這黃線,任何一個方向都不行。在圖的上部,你可以看到白色的虛線,它意味着你可以自由的穿越它,只要是安全的。那白色的實線呢?它代表你可以穿越,但你必須要買票,或者交點過路費。

 

好了,如果你覺得前面的比喻沒有使你明白的話,讓我們來講點實在的東西。

 

首先, 我們來看C和M之間的綠色箭頭,這箭頭的方向就代表着“發起對話”的方向,也就是說,發起對話的是C,而做出回答的是M。C可以問M各種各樣的問題,但M只是回答C的問題或要求,它不可以主動的向C要求什麼。還記得虛線是暢通無阻的意思吧,所以,C知道M的所有的事情,如果用代碼來說明這件事情,就是說,C可以導入M的頭文件或是M的接口(API)。因爲C可以通過M的API,所以它就可以肆無忌憚的向M要求這要求那了。

 

我們再來看看另外的一個綠色箭頭,它是在C和V之間,和前一個綠色箭頭的意義一樣,它代表C可以直接地向V進行交流。你可以想想,C要把V放到屏幕上,並設置V的屬性,告訴它們什麼時候從屏幕上消失,把它們分成組等等。如果C不能自由的向V發號施令的話,程序的顯示將會多麼的困難,所以,C可以毫無限制地向V說話。

 

可能你已經注意到了,這個箭頭上還有outlet(輸出口),outlet可以看作是從C指向V的指針,它在C中被定義。outlet給我們提供了很大的方便,它使我們在C的內部就可以輕鬆準確地向V施令。C可以擁有很多的outlet,可以不止一個,這也使它可以更高效的和V進行交流。

 

那M和V之間可以交流麼?還記得黃線的意思麼?完全不可以通過,所以我們是不允許M和V進行交流的。這是因爲我們不希望這三部分之間有過多的交流,你想想,假如V在顯示時出現了問題,比如有一個圖形沒有顯示出來,我們就要去查找錯誤,因爲C可以和V交流,M也可以和V交流的話,我們就要去檢查兩個部分。相反的,只有C可以和V交流的話,在出錯時,我們就只需要去C那裏查找原因,這樣查找錯誤不就很是簡單了麼?所以,我們不允許M和V之間有直接的聯繫,這也是在它們兩之間有兩根黃線的原因。

 

好的應用程序要具備與用戶交互的能力。如果沒有良好的交互性,程序的功能將會受到很大的限制。在MVC中,V是和用戶直接接觸的,用戶看不到M和C,所以,程序與用戶的交互必須通過V來實現,但V只是視圖而已,它並不能完全處理用戶的要求,所以,這就要求V必須有某種手段來向C發送信息,移交用戶的交互要求。這手段就是前面白色實線代表的過路費,你知道V不能知道C的一切,但它可以通過某種“手段”來和C進行交流,移交用戶交互責任。

 

我們接下來討論V是如何向C發送信息的。V對C的交流有三種不同的方式。

 

第一種我們稱爲目標操作(target-action)。它是這樣工作的,C會在自己的內部“懸掛”一個目標(target),如圖中的紅白相間的靶子,對應的,它還會分發一個操作(action,如圖中的黃色箭頭)給將要和它交流的視圖對象(可能是屏幕上的一個按鈕),當按鈕被按時,action就會被髮送給與之對應的target,這樣V就可以和C交流了。但是在這種情況下,V只是知道發送action給對應的target,它並不知道C中的類,也不知道它到底發送了什麼。target-action是我們經常使用的方法。

 

第二種方式我們叫做委託(delegate)。有時候,V需要和C進行同步,你知道,用戶交互不僅僅是什麼按按鈕,劃滑塊,還有很多種形式。好了,讓我們來看看圖中的delegate黃色箭頭,你發現箭頭上又分出了四個小箭頭:should,did,will,還有一個沒標註的。絕大部分的delegate信息都是should,will,did這三種形式。和英文意思相對應,should代表視圖對象將詢問C中的某個對象“我應該這麼做麼?”,舉個例子,有一個web視圖,有人點擊了一個鏈接,web視圖就要問“我應該打開這個鏈接麼?這樣做安全麼?”。這就是should信息。那will和did呢?will就是“我將要做這件事了”,did就是“我已經做了這件事”。C把自己設置爲V的委託(delegate),它讓V知道:如果V想知道更多的關於將如何顯示的信息的話,就向C發送delegate信息。通過接受V發過來的delegate信息,C就會做出相應的協調和處理。還有一點,每個V只能有一個delegate。

 

第三種方式就是數據源(datasource),你知道,V不能擁有它所要顯示的數據,記住這點非常重要。V希望別人幫助它管理將要顯示的數據,當它需要數據時,它就會請求別人的幫助,把需要的數據給它。再者,iphone的屏幕很小,它不能顯示包含大量信息的視圖。看圖中的datasource箭頭,和delegate類似,V會發送cout,data at信息給C來請求數據。

 

好了,這就是V給C發送信息的三種形式。

 

最後一個問題。你看到M和C之間的白線,這意味着M不可以直接地,沒有限制的對C進行交流。但有時,這個方向的交流是必要的。當M中的一些東西發生變化時,C需要了解這些變化,那我們怎麼才能讓C知道M的變化呢?通知(Notification)和KVO是解決問題的好方法。它們是這樣工作的,當M中的某些東西發生變化時,他們會向C發出通知“嘿,老兄,注意了啊,我這發生變化了”,或者他們會發出指向變化的指針給C,或其他什麼的。總之,他們的工作模式是這樣的。

 

總結: 

C對M:API
C對V:Outlet
V對C:Target-action, Delegate,Datasource
M對C:Notification,KVO

 


發佈了18 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章