干貨-MVC你認識多少

這幾天在開始準備項目的重構(gòu),之前在一篇技術(shù)文章上看到關(guān)于控制器的view相關(guān)知識的時候,偶然發(fā)現(xiàn)自己對于MVC這個在iOS開發(fā)中非常常見的設(shè)計模式其實并不是非常透徹,今天偶然看到一篇文章,講的挺好的,分享一下,感謝[海強_hq ](http://www.lxweimin.com/users/65fba9aae4c 的文章

MVC是一種在iOS開發(fā)中常見的設(shè)計模式,今天主要分析下MVC的原理和它的交流方式。

一、MVC的概念
MVC是Model-View-Controller,就是模型-視圖-控制器,這些都是什么東西呢?

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

關(guān)于Model

Model = 你的程序是什么(而不是你的程序是如何顯示的)讓我們舉個例子,我們上中學(xué)的時候,我們的步步高電子詞典中有個游戲叫“雷霆戰(zhàn)機”,也就是“打飛機”的游戲,Model就是:你的小飛機的攻擊力是多少?你的小飛機上裝的是什么武器,炮彈,導(dǎo)彈,還是激光炮?你的小飛機還有多少血?等等。再概括點說,就是你的程序?qū)⒁獙崿F(xiàn)的功能,或者是它所能干的事情。

關(guān)于Controller

Controller = 如何使你的模型呈現(xiàn)給用戶(程序邏輯)Controller是程序內(nèi)部的邏輯,大多情況下你將看不到它,它將Model和View捆綁在一起,它將處理用戶的輸入,例如,你按開炮的鍵子,Controller就會通過內(nèi)部的邏輯來處理你的要求,并在屏幕上做出相應(yīng)的顯示,你將看到屏幕上的小飛機發(fā)出炮彈擊中敵機。這也是Controller控制View的顯示的例子。所以你可以把Controller看成是連接M和V的橋梁。

關(guān)于View

View = 在屏幕上你所看到的(是你的Controller的“奴才”)接著前面的小飛機,View就是:你的小飛機是什么樣子的,有一個還是兩個翅膀,有幾挺槍炮;還有,你的飛機在屏幕上的位置等等。總之,你在屏幕上看到的組件都可以歸類為View。MVC可以幫助確保幫助實現(xiàn)程序最大程度的可重用性。各MVC元素彼此獨立運作,通過分開這些元素,可以構(gòu)建可維護,可獨立更新的程序組建。

二、M V C之間的交流模式
好了,現(xiàn)在我們來討論MVC中各個元素之間的交流方式。
我們把程序分成三個部分,但并不希望他們完全獨立,因為那樣的話,我們的程序?qū)⒑翢o意義和功能而言。它們之間必然存在某種聯(lián)系,使它們能有機的成為一個整體來實現(xiàn)各種強大的功能。而這種聯(lián)系就是我們提到的交流方式。我們來看看下面的圖,此圖出自斯坦福大學(xué)CS193課程的課件。

MVC的交流

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

C和M之間

好了,如果你覺得前面的比喻沒有使你明白的話,讓我們來講點實在的東西。首先, 我們來看C和M之間的綠色箭頭,這箭頭的方向就代表著“發(fā)起對話”的方向,也就是說,發(fā)起對話的是C,而做出回答的是M。C可以問M各種各樣的問題,但M只是回答C的問題或要求,它不可以主動的向C要求什么。還記得虛線是暢通無阻的意思吧,所以,C知道M的所有的事情,如果用代碼來說明這件事情,就是說,C可以導(dǎo)入M的頭文件或是M的接口(API)。因為C可以通過M的API,所以它就可以肆無忌憚的向M要求這要求那了。

C和V之間

我們再來看看另外的一個綠色箭頭,它是在C和V之間,和前一個綠色箭頭的意義一樣,它代表C可以直接地向V進行交流。你可以想想,C要把V放到屏幕上,并設(shè)置V的屬性,告訴它們什么時候從屏幕上消失,把它們分成組等等。如果C不能自由的向V發(fā)號施令的話,程序的顯示將會多么的困難,所以,C可以毫無限制地向V說話。可能你已經(jīng)注意到了,這個箭頭上還有outlet(輸出口),outlet可以看作是從C指向V的指針,它在C中被定義。outlet給我們提供了很大的方便,它使我們在C的內(nèi)部就可以輕松準確地向V施令。C可以擁有很多的outlet,可以不止一個,這也使它可以更高效的和V進行交流。

M和V之間

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

小結(jié)

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

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

目標操作

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

代理/委托

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

數(shù)據(jù)源

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

小結(jié)

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

下面是我們的一個總結(jié),cocoa忠實于MVC,所以理解cocoa的MVC是我們關(guān)鍵的開始,希望這些能使你明白一些。

C對M:APIC對V:OutletV對C:Target-action, Delegate,DatasourceM對C:Notification,KVO

本文轉(zhuǎn)自:http://www.lxweimin.com/p/994047216a26

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容