MVC、PMVC框架和模式的理解
MCV,有些地方叫框架,有些地方叫設(shè)計(jì)模式,連度娘的搜索名詞都叫"MVC框架",解釋說明叫mvc模式,詞條說明"mvc一般指mvc框架",很難讓人不混淆。
mvc的詞義很好理解:m指業(yè)務(wù)模型、v指用戶界面,c是控制器。
很多資料上說框架和模式還是有區(qū)別的,干嘛不解釋的更清晰一點(diǎn)呢?框架和模式不是一個(gè)東西,這么說不行嗎?那么我就是這么理解,框架是框架,模式是模式??蚣苁菍?shí)實(shí)在在存在的,是可以用代碼實(shí)現(xiàn)的,很多地方都有框架源碼,框架通常是代碼重用,比如一套代碼框架,很多應(yīng)用都可以復(fù)用,它甚至可以直接執(zhí)行,這叫框架。而模式,它是一種思想,是對(duì)在某種環(huán)境中反復(fù)出現(xiàn)的問題以及解決該問題的方案的描述,它比框架更抽象,它只有在實(shí)例化的時(shí)候才可以說:“你看,我這個(gè)類用了單例模版,你看我這個(gè)類是用觀察者模式實(shí)現(xiàn)的,用來解決各界面間的聯(lián)系。”設(shè)計(jì)模式是比框架更小的元素,一個(gè)框架中往往含有一個(gè)或多個(gè)設(shè)計(jì)模式,框架總是針對(duì)某一特定應(yīng)用領(lǐng)域,但同一模式卻可適用于各種應(yīng)用?;蛘哒f,框架是一本書,設(shè)計(jì)模式書中的知識(shí)使用的思想;或者說《西游記》中使用了排比句,感嘆句,等等,《水滸傳》也使用了排比句,感嘆句,等等,這些句子的類型就是一種設(shè)計(jì)模式,《西游記》或《水滸傳》的大綱就是框架,套路通用,內(nèi)容不同。
所以說,通常說的mvc模式,你可以先把它理解成一種思維方式,而mvc框架把這種思維方式落到實(shí)處,通過代碼的方式強(qiáng)制性地使應(yīng)用程序的輸入、處理和輸出分開。使用MVC應(yīng)用程序被分成三個(gè)核心部件:模型、視圖、控制器;
大致理解了框架和模式的區(qū)別。就可以更好的去理解mvc的模式并去實(shí)現(xiàn)它。
在mvc的編程思想中:
V即View視圖是指用戶看到并與之交互的界面。比如由html元素組成的網(wǎng)頁(yè)界面,或者軟件的客戶端界面。在視圖中其實(shí)沒有真正的處理發(fā)生,它只是作為一種輸出數(shù)據(jù)并允許用戶操作的方式。
M即model模型是指模型表示業(yè)務(wù)規(guī)則。在MVC的三個(gè)部件中,模型擁有最多的處理任務(wù)。被模型返回的數(shù)據(jù)是中立的,模型與數(shù)據(jù)格式無(wú)關(guān),這樣一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù),由于應(yīng)用于模型的代碼只需寫一次就可以被多個(gè)視圖重用,所以減少了代碼的重復(fù)性。
C即controller控制器是指控制器接受用戶的輸入并調(diào)用模型和視圖去完成用戶的需求,控制器本身不輸出任何東西和做任何處理。它只是接收請(qǐng)求并決定調(diào)用哪個(gè)模型構(gòu)件去處理請(qǐng)求,然后再確定用哪個(gè)視圖來顯示返回的數(shù)據(jù)。
MVC的好處在于它能為應(yīng)用程序處理很多不同的視圖,代碼復(fù)用,更清晰的視圖和邏輯數(shù)據(jù)分離,視圖就是視圖,邏輯就是邏輯,數(shù)據(jù)就是數(shù)據(jù)。它的優(yōu)點(diǎn):
1.耦合性低
視圖層和業(yè)務(wù)層分離,這樣就允許更改視圖層代碼而不用重新編譯模型和控制器代碼,同樣,一個(gè)應(yīng)用的業(yè)務(wù)流程或者業(yè)務(wù)規(guī)則的改變只需要改動(dòng)MVC的模型層即可。因?yàn)槟P团c控制器和視圖相分離,所以很容易改變應(yīng)用程序的數(shù)據(jù)層和業(yè)務(wù)規(guī)則。
2.重用性高
MVC模式允許使用各種不同樣式的視圖來訪問同一個(gè)服務(wù)器端的代碼,因?yàn)槎鄠€(gè)視圖能共享一個(gè)模型,它包括任何WEB(HTTP)瀏覽器或者無(wú)線瀏覽器(wap),比如,用戶可以通過電腦也可通過手機(jī)來訂購(gòu)某樣產(chǎn)品,雖然訂購(gòu)的方式不一樣,但處理訂購(gòu)產(chǎn)品的方式是一樣的。由于模型返回的數(shù)據(jù)沒有進(jìn)行格式化,所以同樣的構(gòu)件能被不同的界面使用。
3.部署快,生命周期成本低
MVC使開發(fā)和維護(hù)用戶接口的技術(shù)含量降低。使用MVC模式使開發(fā)時(shí)間得到相當(dāng)大的縮減,它使程序員(Java開發(fā)人員)集中精力于業(yè)務(wù)邏輯,界面程序員(HTML和JSP開發(fā)人員)集中精力于表現(xiàn)形式上。
4.可維護(hù)性高
分離視圖層和業(yè)務(wù)邏輯層也使得WEB應(yīng)用更易于維護(hù)和修改。
mvc的解釋和優(yōu)點(diǎn)都說完了,可是我為什么要用這種思想,為什么非得把m\v\c分離,我寫在一個(gè)文件中不行嗎?我用它不是更復(fù)雜了嗎?
參考一個(gè)網(wǎng)上的例子:
我要做一個(gè)界面,于是我寫了一個(gè)代碼文件,這個(gè)代碼文件控制界面的所有邏輯,很簡(jiǎn)單對(duì)不對(duì),非常合理。
后來又要開發(fā)一個(gè)客戶端的界面,也很簡(jiǎn)單,每多一個(gè)界面寫一個(gè)代碼文件與之對(duì)應(yīng)即可。非常合理。
但是問題來了,比如游戲登陸的時(shí)候,我請(qǐng)求到了玩家的信息,而這個(gè)信息要在很多界面使用,我不希望每個(gè)界面都要向服務(wù)器去請(qǐng)求這個(gè)信息,這樣消耗太大。但是如果我這個(gè)信息存在登陸界面,后面的界面要訪問這個(gè)信息的時(shí)候,登陸界面都關(guān)掉了,不太好拿到。
于是我寫了一個(gè)單獨(dú)的文件來存儲(chǔ)這個(gè)信息。非常合理,存儲(chǔ)數(shù)據(jù)的文件出現(xiàn)了。到目前出現(xiàn)了兩種類型的文件,為了方便閱讀代碼結(jié)構(gòu)和查閱代碼,就給它們?nèi)€(gè)名字吧,我把那些全局要使用的信息文件稱為model文件,把處理界面邏輯的文件稱為view文件。
但是還有個(gè)大問題,我所有的界面上都會(huì)有一個(gè)后退按鈕,它的功能只是退到當(dāng)前界面的上一級(jí)界面。這時(shí)候,我似乎要存一個(gè)所有打開界面的堆棧,讓后退的時(shí)候知道它要退到哪一個(gè)節(jié)目。而且因?yàn)槊總€(gè)界面有后退功能,我還想統(tǒng)一去處理后退按鈕的邏輯。于是我就寫了一個(gè)單獨(dú)的文件,里面存了界面打開的堆棧,并統(tǒng)一實(shí)現(xiàn)了后退邏輯。因?yàn)槲乙S護(hù)這個(gè)堆棧,所以打開界面的時(shí)候,我也提供了一個(gè)統(tǒng)一的接口,好讓我知道有界面打開,以便存到堆棧里面,這個(gè)文件似乎叫view和model都不合理。好吧,那我再取一個(gè)名字,就叫controller了。是不是和mvc有點(diǎn)像,不是像,它就是mvc,并不是先有了這種思想,才把它套用到各種應(yīng)用中,而是各種應(yīng)用在處理各種問題時(shí)提供的解決方案有了相通的地方,牛逼的開發(fā)者把這些相同的解決方案思想總結(jié)了一下,就出現(xiàn)了mvc設(shè)計(jì)模式,那么mvc框架也就應(yīng)運(yùn)而生。那么可能又有疑問了,既然mvc能這么自然的寫出來了,我還要框架干什么?
這么說確實(shí)沒毛病,但框架有點(diǎn)好處,在起步的時(shí)候,你的大致方向就給你規(guī)劃好了,細(xì)節(jié)的地方,會(huì)更加統(tǒng)一,按照框架走,越走越平坦。它有它的好處,也有它的缺點(diǎn),就像人生路啊,在你出生的時(shí)候,父母就給你規(guī)劃好了未來,步步都是鋪好的路,它不會(huì)歪不是么,它沒有坑不是么?它很順不是么?但它也就這么著了。。。悲哀啊。
我不是非要依賴它,而是走一條新的路,太難了。。。
PMVC
在理解了mvc的基礎(chǔ)上,pmvc會(huì)相對(duì)更好理解一些了。
PMVC是一個(gè)框架,一個(gè)實(shí)現(xiàn)了mvc模式的框架,你可以把它理解為另一個(gè)版本的mvc框架,只是它改了一些實(shí)現(xiàn)方式,重新起了個(gè)名字,中心思想還是mvc思想。
貼一張官方的圖:

大致看了一下這張圖,是不是又懵逼了?我理解的mvc沒這么復(fù)雜啊?不就是分成model、view、controller三大類嗎?這上面又是Mediator,又是Facade、又是Proxy的,圈圈框框的是什么玩意兒?密密麻麻的箭頭,玩自動(dòng)追蹤吶?!玩吶?!
不著急,先拋開箭頭不看。
上圖中有3個(gè)大圈圈就是剛剛說的Model、View、Controller
自己寫MVC的時(shí)候,有很多View,也有很多Model,可能也會(huì)有很多Controller。但是PMVC這里都只有一個(gè)。這還得慢慢解釋。
以View、Model、Controller為中心,分開來看。
View邊上很多小圈Mediator,這些Mediator就是我們寫的一個(gè)個(gè)控制界面的代碼文件,而這些Mediator文件都統(tǒng)一由View管理。
//TODO更多補(bǔ)充
Model邊上有很多Proxy,Proxy右邊又有很多Obj。
這里Obj其實(shí)就是我們寫的一個(gè)個(gè)存全局信息的文件,它們都繼承自DataObjects。
你可以認(rèn)為DataObjects和Obj才是真正的Model,但是在PMVC里面,它將Model的概念稍微放大了一點(diǎn)。Model包括圖中的:Model、Proxy、DataObjects、Obj
這里多了一層Proxy,主要是讓Obj文件的信息,不直接在各種地方讀和寫,而讓一個(gè)Proxy來負(fù)責(zé)一個(gè)或多個(gè)Obj文件的讀和寫。這樣可以保證數(shù)據(jù)讀寫的邏輯在一塊,以后要統(tǒng)一加個(gè)啥處理,都比較簡(jiǎn)單。當(dāng)然這里的Proxy都由統(tǒng)一的Model管理
//TODO更多補(bǔ)充
Controller邊上有很多Command,這些Command就是我們之前說的統(tǒng)一處理打開界面后退界面的真正的Controller文件。而圖中Controller作用是,你需要通過Controller才能調(diào)用Command,而不能直接去調(diào)用Command。所有的Command都通過這個(gè)Controller調(diào)用,自然Controller就一個(gè)了。
但是這里有點(diǎn)要注意的。Command文件里面并不存界面的堆棧信息,界面的堆棧信息一般會(huì)再寫一個(gè)單獨(dú)的文件來存儲(chǔ)。而這個(gè)單獨(dú)的文件在圖上并沒有。
PMVC的設(shè)計(jì)里面Command只寫處理邏輯,要處理的數(shù)據(jù),都是傳進(jìn)去的,所以它本身并不存儲(chǔ)任何數(shù)據(jù)
//TODO更多補(bǔ)充
圖上最左邊的UI、ViewComponents。
我們之前自己寫MVC的時(shí)候,說的過于簡(jiǎn)單了。一般絕大部分客戶端都會(huì)有一個(gè)界面層和界面邏輯層。比如網(wǎng)頁(yè),界面層是HTML,界面邏輯層是JS。Unity里面,界面層是Perfabs,邏輯層是c#/js代碼。
所以這里面的UI/ViewComponents主要是對(duì)應(yīng)界面上的布局,它有自己的事件系統(tǒng),比如按鈕的點(diǎn)擊,界面的拖拽等等。這些事件系統(tǒng),會(huì)被后面的邏輯層:Mediator監(jiān)聽和處理
//TODO更多補(bǔ)充
關(guān)于Mediator的設(shè)計(jì)還有點(diǎn)需要注意。
(1)Mediator里面可以引用多個(gè)UI。比如我有個(gè)頁(yè)面,上面是一個(gè)通用的玩家信息,下面是自己的獨(dú)有界面,所以我可能會(huì)同時(shí)引用兩個(gè)UI文件。
(2)Mediator里面也可以引用Mediator。還是這個(gè)界面有個(gè)通用的玩家信息,而且這個(gè)玩家信息的顯示數(shù)據(jù)以及交互邏輯都是通用的。那么可以給這個(gè)玩家信息UI寫一個(gè)獨(dú)立的Mediator,然后在需要的界面Mediator里面,再引用這個(gè)玩家信息Mediator就可以。
總結(jié)而言,總體上,每個(gè)界面一個(gè)Mediator。但是如果界面中的某一塊,比較通用,可以單獨(dú)抽出來,做成一個(gè)Mediator,在需要的Mediator里面引用
最后就是圖中的剩余部分,F(xiàn)acade,這個(gè)Facade其實(shí)就是一個(gè)沒有任何意義的對(duì)外入口。
怎么說呢,PMVC設(shè)計(jì)者希望你不需要關(guān)心Model、View、Controller。所以寫了一個(gè)Facade。
Facade提供了Model、View、Controller所有的對(duì)外接口,然后你只要調(diào)用Facade的這個(gè)接口就可以了。而Facade只是把你的調(diào)用,轉(zhuǎn)給了里面的Model、View、Controller去執(zhí)行而已。它自己啥都不干
//TODO更多補(bǔ)充
圖是說完了,但具體怎么實(shí)現(xiàn),還是沒說清楚,紙上談兵可不行,PMVC官網(wǎng)提供了非常多的語(yǔ)言版本的源碼,版本里面的邏輯都是一模一樣的,可以選擇你熟悉的語(yǔ)言下載
具體怎么通過Controller去調(diào)用Command呢?
因?yàn)槭莄ocoscreator做的項(xiàng)目,所以這里下載的是Typescript的版本
PMVC沒有使用任何第三方的事件系統(tǒng),因?yàn)樗M缯Z(yǔ)言,所以自己做了一個(gè)消息系統(tǒng),來代替事件系統(tǒng)的功能。
如果實(shí)際的項(xiàng)目中使用了PMVC,那么你就不需要,也不應(yīng)該在使用其他事件系統(tǒng)了(主要是怕混淆),UI自帶的事件系統(tǒng)(點(diǎn)擊,拖拽等事件)除外;
源碼的PMVC是一個(gè)多例類。但是很多時(shí)候只需要用單例就可以了,這里也只討論單例。而代碼里面所有關(guān)于MultitonKey字段的賦值、使用,都是多例才需要考慮的問題。
所以所有MultitonKey相關(guān)的代碼,都不需要管
從Observer文件夾開始。Observer文件夾里面有3個(gè)文件:Notification、Notifier、Observer

1.Notification,Notification就是剛剛說的消息,消息里面就3個(gè)字段,Name Body Type。所有的消息都是通過Name來唯一標(biāo)識(shí)的,所以呢,消息的Name都是全局唯一的,如果不唯一就會(huì)有問題。其次就是Body,大部分消息都需要Body,因?yàn)樘幚硐⒌娜?,很可能依賴于Body里面的信息。而Type只是一個(gè)補(bǔ)充,可有可無(wú)。
Notification不繼承任何父類,只實(shí)現(xiàn)INotification接口。
這里補(bǔ)充一下:
extends與implements的不同
1、在類的聲明中,通過關(guān)鍵字extends來創(chuàng)建一個(gè)類的子類。
一個(gè)類通過關(guān)鍵字implements聲明自己使用一個(gè)或者多個(gè)接口。?
extends 是繼承某個(gè)類,?繼承之后可以使用父類的方法, 也可以重寫父類的方法;?
implements 是實(shí)現(xiàn)多個(gè)接口,?接口的方法一般為空的, 必須重寫才能使用?
接口實(shí)現(xiàn)的注意點(diǎn):??
a.實(shí)現(xiàn)一個(gè)接口就是要實(shí)現(xiàn)該接口的所有的方法(抽象類除外)。?
b.接口中的方法都是抽象的。 ?
c.多個(gè)無(wú)關(guān)的類可以實(shí)現(xiàn)同一個(gè)接口,一個(gè)類可以實(shí)現(xiàn)多個(gè)無(wú)關(guān)的接口。
接著上面說,Notification一般情況也不會(huì)有人繼承它,就是一個(gè)獨(dú)立的消息名稱,和消息數(shù)據(jù)的封裝。
2.Notifier,Nofier沒有父類,很多人繼承它。只實(shí)現(xiàn)接口INotifier,它只有一個(gè)方法,就是SendNotification。里面的其他部分都是多例的處理,前面說了,不用管。例如Facade,如果是單例,就是全局唯一的。

那重點(diǎn)要看看,誰(shuí)繼承了它。
可以認(rèn)為,所以繼承它的類,才能發(fā)送Notification,不然沒有提供這個(gè)方法,你想發(fā)也發(fā)不了。
繼承它的是Command、Mediator、Proxy。
//TODO更多補(bǔ)充
3.)Observer,沒有父類,沒有子類,只實(shí)現(xiàn)接口IObserver
。如果你去使用PMVC,你可能永遠(yuǎn)不會(huì)遇到有關(guān)Observer的問題。
所以這個(gè)類,是PMVC內(nèi)部使用的類。但是你要理解PMVC,這個(gè)Observer卻非常關(guān)鍵
Observer有非常簡(jiǎn)單,兩個(gè)成員,一個(gè)委托(NotifyMethod),一個(gè)Object(NofityContext)。委托是用來處理Notification的委托,它只接受一個(gè)參數(shù)Notification,并且沒有返回值。

那Object(NofityContext)是干啥的呢?
首先,我們看一下Observer的使用。Observer的創(chuàng)建只有兩個(gè)地方。
①Controller里面 new Observer(ExecuteCommand, this) 這里this就是全局唯一的Controller
②View里面 new Observer(mediator.HandleNotification, mediator)


所以O(shè)bserver里面的Object只可能是2個(gè)東西,全局唯一的Controller,或者某一個(gè)Mediator
再看一下使用,所有New出來的Observer都是通過View.RegisterObserver來使用
里面是存在了一個(gè)observerMap中,讓Notification.Name 能和Observer對(duì)應(yīng)起來
值得注意的是,Notification.Name可以對(duì)應(yīng)一個(gè),或者多個(gè)Observer。
那么就看一下observerMap的使用。也就用在了3個(gè)地方,
View.RegisterObserver
View.NotifyObservers
View.RemoveObserver
NotifyObservers的時(shí)候,不需要使用Observer里面的Object(NotifyContext)
RemoveObserver的時(shí)候,需要使用Observer里面的Object(NotifyContext)
所以O(shè)bserver里面的NofityContext只在RemoveObserver的時(shí)候才有用了。
而RemoveObserver是在什么時(shí)候使用的呢,兩個(gè)地方
RemoveMediator
RemoveCommand
所以說NotifyContext是記錄這個(gè)Observer中的委托是誰(shuí)注冊(cè)的。
在刪除的時(shí)候,不能把某一個(gè)Notification.Name下的所有委托都刪除了,只能誰(shuí)注冊(cè)的誰(shuí)刪除
>>>接下來看一下所有的Facade外觀提供的接口,也就是pmvc所有提供的接口了。
RegisterCommand
RegisterProxy
RegisterMediator
SendNotification
有Register就有對(duì)應(yīng)的Retrieve(通過Notification.Name取)、Remove
注意:代碼中實(shí)現(xiàn)時(shí),register和remove是一一對(duì)應(yīng)的。原因:內(nèi)存泄漏
RegisterCommand是Controller里面提供的接口,綁定消息名稱和Command的關(guān)系。也就是前面說的,你要執(zhí)行Command,沒有辦法直接執(zhí)行,必須通過這個(gè)接口注冊(cè)綁定關(guān)系,然后發(fā)送指定的Notification。所以Controller管理Command
RegisterMediator是View里面提供的接口
所以說View管理Mediator。那么RegisterMediator具體是干什么呢。其實(shí)就是給Mediator綁定消息和消息的處理函數(shù)。
具體的,每個(gè)Mediator里面會(huì)有個(gè)ListNotificationInterests,里面寫著它所有關(guān)心的消息,以及一個(gè)統(tǒng)一的消息處理方法HandleNotification。
注冊(cè)Mediator就是把這些消息都綁定到這個(gè)統(tǒng)一處理的方法上,然后Mediator內(nèi)部可以在HandleNotification中根據(jù)消息Name和Body再具體實(shí)現(xiàn)處理。
剛剛說的Observer里面存了一個(gè)NotifyContext,也就是對(duì)應(yīng)的Mediator,所以可以在RemoveMediator的時(shí)候,刪除掉本界面相關(guān)的消息綁定
RegisterProxy,Proxy是Model管理的,自然這個(gè)接口也是Model提供的。
但是proxy和前面的Mediator、Command不同,因?yàn)樗蚈bserver無(wú)關(guān)。
前面2個(gè)注冊(cè)的目的就是綁定消息名稱和消息處理函數(shù)的關(guān)系。但是Proxy不干這個(gè)事情。
那RegisterProxy干啥呢?
對(duì)的,它啥都不干。就是存了一個(gè)Proxy和Proxy.Name的對(duì)應(yīng)關(guān)系,讓你在需要指定Proxy的時(shí)候可以拿到而已
SendNotification,這個(gè)就是View里面的NotifyObservers,也就是使用observerMap,找到Notification對(duì)應(yīng)的所有委托,并執(zhí)行。
所以SendNotification的過程,就是找到所有委托并執(zhí)行,它中間沒有任何間隔,不會(huì)說等到下一幀啥的再執(zhí)行
說明:
1、RegisterCommand(string notificationName, Func<ICommand> commandFunc)
咋一看,就是綁定消息名稱,和Command的關(guān)系。但仔細(xì)一看,這里有個(gè)奇怪的地方
它不直接傳一個(gè)ICommand,而是傳一個(gè)委托,這個(gè)委托返回一個(gè)ICommand。
再看他的使用,在Controller里面,它綁定了Notification.Name和自己固定執(zhí)行函數(shù)ExcuteCommand。
在ExcuteCommand里面,先通過執(zhí)行Func<ICommand>commandFunc這個(gè)函數(shù),獲得一個(gè)ICommand
然后再調(diào)用ICommand里面的固定處理函數(shù)Execute(Notification)
這里是不是多此一舉呢,我直接傳一個(gè)ICommand是不是就可以了呢。
當(dāng)然他這樣做的目的是,實(shí)現(xiàn)前面說的,Command里面只處理邏輯,不保存數(shù)據(jù)。
(也就是官方文檔說的,是無(wú)狀態(tài)的)
因?yàn)镃ontroller是通過這個(gè)傳入的委托執(zhí)行生成的,并不是你傳的,可以認(rèn)為它是一個(gè)全新的。
(當(dāng)然理論上你還是可以通過某些特殊的方式來存數(shù)據(jù),只是會(huì)很麻煩,于是你可能就會(huì)遵從框架的標(biāo)準(zhǔn)了)
注:某些語(yǔ)言中,會(huì)在這里傳一個(gè)類型,然后再ExcuteCommand的時(shí)候,New出來。都是一樣的作用。
2、Mediator、Command、Proxy都可以SendNotification,
或者任意地方你都可以調(diào)用全局的Facade.SendNotification。效果也是一樣的。
也就是發(fā)消息是個(gè)全局通用函數(shù)。
但是綁定消息,只有2個(gè)接口實(shí)現(xiàn),RegisterCommand/RegisterMediator。
也就是沒有提供Proxy綁定消息的方法。所有Proxy里面無(wú)法處理Notification。
3、Mediator/Command/Proxy并沒有一一對(duì)應(yīng)的關(guān)系。
(1)Command是處理一些通用邏輯,以及界面之間的切換邏輯(或者說系統(tǒng)邏輯)。
(2)Proxy是數(shù)據(jù)層的某一塊數(shù)據(jù)的封裝。有很多界面的數(shù)據(jù)只在有限的幾個(gè)界面內(nèi)使用,所以看起來Proxy還是會(huì)對(duì)應(yīng)著幾個(gè)界面。但是事實(shí)上,Proxy和界面沒有任何對(duì)應(yīng)關(guān)系,只是別的地方暫時(shí)沒有使用這塊數(shù)據(jù)而已。
(3)每個(gè)界面必須有一個(gè)Mediator,而除了界面Mediator還有些某一塊子界面的通用Mediator,作為子Mediator加載到需要的界面Mediator中
所以說,上面的線是為了便于理解畫的,亂線并不亂~~
此處感謝《博客園》慈方陽(yáng)的文章《1個(gè)小時(shí)PMVC從入門到精通》,大部分理解和記錄都是參照此文章。僅用于自身學(xué)習(xí)記錄。