最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

PureMvc在CocosCreator項(xiàng)目中的應(yīng)用(一)

2021-11-22 18:13 作者:會(huì)飛的蝸牛007  | 我要投稿

代碼多寫一行,可能就會(huì)多發(fā)現(xiàn)一個(gè)問(wèn)題,在解決問(wèn)題的過(guò)程中,知識(shí)和見識(shí)也在不停的補(bǔ)充。前面剛寫了對(duì)mvc框架的理解,后面又不得不補(bǔ)充,回頭看一下,不得不承認(rèn)見識(shí)仍然淺薄。

寫這篇文章是為了記錄解決問(wèn)題思路,也是備忘,最重要的其實(shí)還是鞏固新學(xué)到的東西。

關(guān)于pmvc的補(bǔ)充,參考了騰訊游戲?qū)W堂、作者ken的文章《PureMVC框架在Unity中的應(yīng)用》,網(wǎng)上有很多抄襲的文章而且不注明出處,這個(gè)就不多說(shuō)了,存在即合理,還是感謝大佬ken的分享。

原文章分了兩部分,第一部分解讀PureMVC框架原理,主要是理論;第二部分通過(guò)一個(gè)簡(jiǎn)單的例子,演示如何在Unity中應(yīng)用PureMVC框架,是實(shí)踐;理論實(shí)踐結(jié)合,簡(jiǎn)單明了,而且語(yǔ)言并不官方,理解起來(lái)很容易。因?yàn)槲乙龅氖莄ocosCreator的項(xiàng)目,所以語(yǔ)言是typescript,實(shí)例也對(duì)應(yīng)的是cocosCreator;

作者ken有一段分享我覺(jué)得特別贊,文章中是這樣說(shuō)的:

我一直認(rèn)為,框架的使用,需要你工作一段時(shí)間以后再去接觸會(huì)比較好,就像孩子踢球一樣,剛開始可以隨心所欲的踢,沒(méi)有什么中前,中后場(chǎng)的概念,球在哪兒,就一股腦兒的追上去搶,幾十雙腳噼里啪啦的,其實(shí),這就是大多數(shù)人剛開始做游戲開發(fā)時(shí)候的狀態(tài),沒(méi)什么框架,代碼硬懟,不注重性能,擴(kuò)展性,重用性等等,BUG層出不窮,只要功能出來(lái)就好,慢慢的,隨著開發(fā)經(jīng)驗(yàn)的不斷豐富,你就會(huì)開始思考,當(dāng)下做的這些事兒,有沒(méi)有更方便,更有效的方法。

這時(shí)候你會(huì)開始注意到,”技戰(zhàn)術(shù)“的作用有多么的重要!?說(shuō)點(diǎn)兒題外話,如果你在工作中,碰到技術(shù)很好的大神,而且又樂(lè)于分享,一定要多向他們請(qǐng)教,因?yàn)槟阏娴目梢陨僮吆芏鄰澛?,并且能夠更快的提升自己,沒(méi)有什么比時(shí)間更有價(jià)值了,這是我一直以來(lái)都?jí)裘乱郧蟮?,也許是我運(yùn)氣不太好,也許是我的工作歷程和很多人都不同的緣故......扯得有些遠(yuǎn)了,無(wú)論是有經(jīng)驗(yàn)的大神告訴你的,還是你通過(guò)搜索引擎查找,你都會(huì)聽到MVC這個(gè)框架,這是個(gè)誕生了將近40年的經(jīng)典框架。

沒(méi)有完美的框架,MVC也是,在MVC的基礎(chǔ)上,又演變出來(lái)了MVP,MVVM,但在本篇文章中,我將只介紹MVC框架的原理和應(yīng)用,理解了MVC框架,將會(huì)更容易的理解MVP,MVVM,甚至是其它一些框架的設(shè)計(jì),比如ECS。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

步入正題:

MVC (Model:數(shù)據(jù) View:視圖組件 Controller:控制邏輯)的原理是將數(shù)據(jù),視圖組件和控制邏輯進(jìn)行分離。讓程序便于修改,更具有擴(kuò)展性,靈活性,可重用性。高內(nèi)聚,低耦合,一直是追求的目標(biāo)。

傳統(tǒng)經(jīng)典的MVC模型雖然將數(shù)據(jù),視圖組件和控制邏輯進(jìn)行了分離,但耦合性還是比較高,所以就有了pureMVC

PMVC在傳統(tǒng)MVC基礎(chǔ)上做了許多的改進(jìn),通過(guò)結(jié)合多個(gè)“設(shè)計(jì)模式”的應(yīng)用,讓耦合性變得更低,也變得更加的易用,在擴(kuò)展性,靈活性,重用性方面也做得更好

設(shè)計(jì)模式的存在,其實(shí)很重要的一個(gè)職責(zé)就是解決耦合性。PureMVC用到的這些設(shè)計(jì)模式,貫穿了整個(gè)游戲框架,即便項(xiàng)目中使用的不是MVC框架,都離不開這些設(shè)計(jì)模式的應(yīng)用,PureMVC中用到了以下的設(shè)計(jì)模式:

1.代理設(shè)計(jì)模式

2.中介者設(shè)計(jì)模式

3.外觀設(shè)計(jì)模式

4.觀察者設(shè)計(jì)模式

5.命令設(shè)計(jì)模式

6.單例設(shè)計(jì)模式

在上面列舉的設(shè)計(jì)模式中,可能有熟悉的、使用過(guò)的,也可能有沒(méi)見過(guò)的,如果沒(méi)見過(guò)沒(méi)用過(guò),這部分的知識(shí)可能需要補(bǔ)充一下了。關(guān)于pmvc中用到的設(shè)計(jì)模式,我在另一篇文章《PureMVC框架中使用到的設(shè)計(jì)模式簡(jiǎn)書》中有把概念和應(yīng)用簡(jiǎn)單的介紹;如果看到這里對(duì)這些并不熟悉,建議先去看一下,有個(gè)大致了解,會(huì)更方便閱讀理解下文的分析。

http://puremvc.org

上面的鏈接是puremvc的官網(wǎng)

可以看到,PureMVC支持了大部分的主流語(yǔ)言,可以很容易的在項(xiàng)目中引入PureMVC

http://puremvc.org/docs/PureMVC_Conceptual_and_Intro.pdf

實(shí)踐手冊(cè),提供了6種語(yǔ)言版本

PureMVC概念圖

官方提供的PureMVC概念圖

先看一下核心層:Model,View,Controller

可以看一下他們身上的箭頭線,Model,View,Controller之間并沒(méi)有任何的直接通信

也就是說(shuō),”改變一個(gè)不影響其它“,這也是為什么不能用傳統(tǒng)的,將數(shù)據(jù),視圖組件和控制邏輯耦合在一起的做的原因,僅改變了一個(gè)UI組件的位置,不應(yīng)該讓數(shù)據(jù)和控制邏輯也進(jìn)行編譯,或者我對(duì)控制邏輯的調(diào)整,不應(yīng)該影響到數(shù)據(jù)部分,而且這也不利于多人協(xié)作開發(fā)

那他們之間沒(méi)有通信,怎么聯(lián)系呢?肯定是要聯(lián)系的啊,降低耦合也不能一點(diǎn)聯(lián)系都沒(méi)有吧?不用著急,聯(lián)系肯定是有的,只不過(guò)使用了其他的手段,讓他們看起來(lái)是陌生人,實(shí)際上還是都流淌著一樣的血脈。

在PureMVC中,Model,View,Controller三者合稱為核心層或核心角色,換句話說(shuō)就是Manager管理類,他們分別定義了字典用于保存引用,以及Register,Add,Remove,Retrieve等方法,將使用到的具體層(Model,View,Controller),保存到字典中進(jìn)行統(tǒng)一管理,這樣,在我需要獲取某一個(gè)具體層時(shí),可以通過(guò)key直接訪問(wèn)到它們

在開發(fā)的過(guò)程中,我要在Contoller中,獲取View以及Model的對(duì)象,修改Mode,更新View,或是在View,我要獲取Model,進(jìn)行一些初始化或是修改的操作(注意,在PureMVC中,并不建議這樣做),在業(yè)務(wù)邏輯很多的情況下,Model,View,Controller之間的頻繁的調(diào)用就會(huì)非常多,耦合性會(huì)變高,如何解決呢?

在PureMVC中,使用了Facade設(shè)計(jì)模式,即外觀設(shè)計(jì)模式。通過(guò)一個(gè)上層的接口來(lái)負(fù)責(zé)所有核心層(Model,View,Controller)的管理和操作

外觀設(shè)計(jì)模式的定義如下:

"為一組子系統(tǒng)或是接口提供一個(gè)統(tǒng)一的界面,以簡(jiǎn)化其復(fù)雜度,降低耦合性"

Facade提供了與核心層通信的唯一接口,以簡(jiǎn)化開發(fā)復(fù)雜度。

其實(shí)概念圖中已經(jīng)說(shuō)明了一切

在Controller中,獲取View和Model,或者View中,獲取Model,均統(tǒng)一使用Facade進(jìn)行管理。這樣就降低了MVC三層之間的耦合性。對(duì)于使用者來(lái)說(shuō),只需要知道Facade類存在就可以了

Facade類是一個(gè)抽象類,如果想要實(shí)現(xiàn)具體的應(yīng)用,可以具體編寫 Facade 的子類,添加或重寫 Facade 的方法。這個(gè)類命名為“ApplicationFacade”(當(dāng)然,命名隨你喜歡)

如前所述,它主要負(fù)責(zé)訪問(wèn)和通知 Model、View 和 Controller 。即管理這三者

Facade 是 Model、View 和 Controller 三者的“經(jīng)紀(jì)人”。實(shí)際編寫代碼時(shí)你并不用導(dǎo)入這三者的類文件,也不用直接使用它們。Facade 類已經(jīng)在構(gòu)造方法包含了對(duì)核心 MVC 三者單例的構(gòu)造

Facade類在構(gòu)造方法中初始化了 Model、View 和Controller 對(duì)象,并把對(duì)它們的引用保存在成員變量。(可以看上圖哦)

這樣,F(xiàn)acade就可以訪問(wèn) Model、View 和 Controller 了。這樣把對(duì)核心層的操作都集中在 Facade,避免開發(fā)者直接操作核心層

在實(shí)際開發(fā)中,應(yīng)用程序都有一個(gè) Facade 子類,這個(gè) Facade 類對(duì)象負(fù)責(zé)初始化 Proxy,Mediator和Command,建立 Command 與 Notification 名之間的映射,或是通過(guò)執(zhí)行一個(gè) Command 來(lái)注冊(cè)所有的 Proxy和 Mediator

這里提到了Command,Proxy和Mediator

Command,Proxy和Mediator之間的對(duì)應(yīng)關(guān)系是這樣的:

Proxy=>Model

Mediator=>View

Command=>Controller

但為什么要增加Proxy,Mediator和Command三個(gè)概念呢,其實(shí)主要也是為了降低耦合性

Model和Proxy對(duì)應(yīng)的具體是什么關(guān)系呢?

截圖是Model和Proxy的關(guān)系圖,有用紅圈標(biāo)注

Model即數(shù)據(jù)(Data Object),比如角色的數(shù)據(jù),包括HP,MP,金幣,等級(jí),經(jīng)驗(yàn),技能等等,在PureMVC中,是通過(guò)Proxy來(lái)進(jìn)行管理

Proxy即代理設(shè)計(jì)模式,“為其它對(duì)象提供代理以控制該對(duì)象的訪問(wèn)”;也就是代理人,在PureMVC中被用來(lái)控制和管理數(shù)據(jù)模型的;Data Object即是以任意結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)的對(duì)象

上面其實(shí)分析過(guò),Model和其他兩大巨頭是沒(méi)有任何直接通信的,對(duì)Model的增刪改查均是通過(guò)Proxy來(lái)處理的,也就是說(shuō),model通過(guò)Proxy來(lái)和外界聯(lián)系。

關(guān)于Proxy代理模式,比如球星-C羅,他的Proxy代理就是C羅團(tuán)隊(duì),有什么商業(yè)合作事宜均通過(guò)C羅團(tuán)隊(duì)進(jìn)行接洽,這樣,C羅就不需要一個(gè)人去面對(duì)來(lái)自四面八方的合作溝通成本(降低耦合性),同時(shí),團(tuán)隊(duì)也可以幫助C羅處理很多的事務(wù),不需要每件事兒都要經(jīng)由C羅的過(guò)目(一定程度上隱藏了其內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)),從代碼角度,也滿足”改變一個(gè)不影響其它“,我對(duì)部分?jǐn)?shù)據(jù)的修改,不應(yīng)該影響到其它的數(shù)據(jù)

繼續(xù)看上面的示意圖,看下Model的箭頭,他只和Facade進(jìn)行交互。上面提到過(guò),這是為了降低耦合性

旁邊的一眾Obj即Model,對(duì)應(yīng)著Proxy,但并不是一個(gè)Model對(duì)應(yīng)一個(gè)Proxy,如果是這樣,就太繁瑣了,比如一個(gè)模塊中,可能包括很多種不同的Model數(shù)據(jù),你可以定義多個(gè)不同的Model,但可以通過(guò)一個(gè)Proxy進(jìn)行管理,這樣更方便

在實(shí)際應(yīng)用中,通常會(huì)以同步的方式取得或設(shè)置Model數(shù)據(jù)。Proxy 可能會(huì)提供訪問(wèn) DataObject 部分屬性或方法的 API,也可能直接提供 Data Object 的引用(但不建議這樣做,我們應(yīng)該保護(hù)Model,提供相應(yīng)的接口來(lái)訪問(wèn))。如果提供了更新 Data Object 的方法,那么在數(shù)據(jù)被修改時(shí)可能會(huì)發(fā)送一個(gè) Notifidation 通知系統(tǒng)的其它部分

上面說(shuō)到了Notification通知,其實(shí)就是觀察者模式,當(dāng)一個(gè)對(duì)象發(fā)生改變的時(shí)候,同時(shí)也需要有很多其它的對(duì)象要對(duì)此做出響應(yīng),這時(shí)候就要使用觀察者模式了,發(fā)布-訂閱的模式,比如我們訂閱了某個(gè)微信公眾號(hào),公眾號(hào)發(fā)表了一篇文章,所有訂閱的用戶都可以收到提醒,這在游戲中無(wú)處不在,當(dāng)Model發(fā)生變化的時(shí)候,通知View組件進(jìn)行更新。那么在View中,就會(huì)有相應(yīng)的方法來(lái)處理Notification通知,并進(jìn)行相應(yīng)的邏輯處理。

注意:Proxy只發(fā)送Notification通知(在數(shù)據(jù)改變的時(shí)候),他并不處理Notification通知,他并不關(guān)心View組件如何變化

Proxy 對(duì)象不應(yīng)該通過(guò)引用、操作 Mediator 對(duì)象來(lái)通知系統(tǒng)它的 DataObject(數(shù)據(jù)對(duì)象)發(fā)生了改變

也就是說(shuō),Mediator可以獲取Proxy,但Proxy中不應(yīng)該獲取Mediator,如果要通知View層進(jìn)行更新,發(fā)送Notification通知即可

(Proxy 不關(guān)心這些 Notification 被發(fā)出后會(huì)影響到系統(tǒng)的什么),這樣Proxy和Mediator之間只存在單向耦合。

Proxy中也包含了一定的邏輯處理的部分,我們把 Domain Logic(域邏輯)盡可能放在 Proxy 中實(shí)現(xiàn),這樣盡可能地做到 Model 層與相關(guān)聯(lián)的 View 層、Controller 層的分離

比如計(jì)算扣稅的函數(shù),如果你將他放在Mediator或是Command中實(shí)現(xiàn),那么就相當(dāng)于把這部分代碼耦合了,比如你的View要重建,或是別的Command也要使用該扣稅函數(shù),那么這部分代碼就無(wú)法得到復(fù)用,所以放在Proxy中是更為合適的

在實(shí)際應(yīng)用中,Model(Data Object) 通常是一個(gè)復(fù)雜的數(shù)據(jù)結(jié)構(gòu),我們經(jīng)常需要引用它的一部分屬性并將類型轉(zhuǎn)化成我們需要的數(shù)據(jù)。

通過(guò)getter 和 setter 屬性,它可以很好地幫助我們解決這種頻繁的類型轉(zhuǎn)換問(wèn)題。

這可能需要定義不同的多個(gè)類型 getter 來(lái)取得 Data Object 某部分的數(shù)據(jù)。

?get {return data as ArrayCollection;}

?}

關(guān)于View,View即視圖組件,和Model層一樣,也是通過(guò)”中介“來(lái)進(jìn)行管理,View是由Mediator來(lái)操作具體的視圖組件(View Component)。包括:添加事件監(jiān)聽器 ,發(fā)送或接收 Notification ,直接改變視圖組件的狀態(tài)

Mediator(中介者設(shè)計(jì)模式):“用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互“(重交互, 強(qiáng)邏輯)

View Component即UI上的各種控件,按鈕,列表,滾動(dòng)條等等。

這樣做實(shí)現(xiàn)了把視圖和控制它的邏輯分離開來(lái)。對(duì)于View中組件的定義和初始化都在Mediator中定義和實(shí)現(xiàn),這樣即使UI重建,也只是更改Mediator

因?yàn)?Mediator 也會(huì)經(jīng)常和 Proxy 交互,所以經(jīng)常在 Mediator 的構(gòu)造方法中取得Proxy 實(shí)例的引用并保存在 Mediator 的屬性中,這樣避免頻繁的獲取 Proxy 實(shí)例帶來(lái)的性能開銷

這里可以看到,通常View和Mediator是一對(duì)一的關(guān)系,但有些View會(huì)相對(duì)復(fù)雜,有多個(gè)子UI組成,Mediator中也可以有多個(gè)View Component引用(同一功能的不同子UI)

但如果Mediator過(guò)于龐大,就要進(jìn)行拆分,在拆分后的子模塊的 Mediator 里處理要比全部放在一起更好。這部分工作需要慢慢的重構(gòu)

關(guān)于轉(zhuǎn)化 View Component 類型:(這部分和Model是一樣的處理方式 )

這個(gè) Mediator 子類會(huì)在構(gòu)造函數(shù)中把它的 View Component 傳參給父類,它會(huì)在內(nèi)部賦值給一個(gè) protect 屬性:viewComponent,并傳化為Object 類型

Mediator 被構(gòu)造之后,你可以通過(guò)調(diào)用它的 setViewComponent 函來(lái)動(dòng)態(tài)給它的 View Component 賦值(修改)。之后,每一次需要訪問(wèn)這個(gè) Object 的 API 時(shí),你都要手動(dòng)把這個(gè) Object轉(zhuǎn)化成它的真正類型。這是一項(xiàng)煩瑣重復(fù)的工作。

和上面的Model一樣,Mediator中保存了View的引用,我們最緩存下來(lái)。

結(jié)合上面說(shuō)的,Mediator其實(shí)保存了view和proxy的引用

Mediator通常要做的事:

1.檢查或修改 View Component 的屬性

2.檢查或修改 Proxy 對(duì)象公布的屬性

3.發(fā)送一個(gè)或多個(gè) Notification ,通知?jiǎng)e的 Mediator 或Command 作出響應(yīng)(甚至有可能發(fā)送給自身)

但要注意一點(diǎn),業(yè)務(wù)邏輯(Business Logic)應(yīng)該放在Command中,而非Mediator中!

實(shí)際上Mediator并不處理復(fù)雜的邏輯。像Model那樣,域邏輯的部分,可以放在Mediator中實(shí)現(xiàn),減少與Controller的耦合性,也提高了重用性

注意:不要將檢測(cè)或是對(duì)VC(View Component以及Proxy)屬性的修改當(dāng)作是業(yè)務(wù)邏輯(Business Logic)

下面是大佬的一些經(jīng)驗(yàn)分享:

1.如果有多個(gè)的 Mediator 對(duì)同一個(gè)事件做出響應(yīng),那么應(yīng)該發(fā)送一個(gè) Notification,然后相關(guān)的 Mediator 做出各自的響應(yīng)。(觀察者模式)

(比如說(shuō),你當(dāng)前屏幕上顯示了3個(gè)UI,每個(gè)UI上都顯示著玩家的金錢數(shù)量,當(dāng)金錢發(fā)生變化的時(shí)候,Proxy應(yīng)該發(fā)送一個(gè)相應(yīng)的Notification通知,然后3個(gè)UI接受通知并進(jìn)行View的更新)

2.如果一個(gè) Mediator 需要和其他的 Mediator 進(jìn)行大量的交互,那么一個(gè)好方法是利用 Command 把交互步驟定義在一個(gè)地方。

3.不應(yīng)該讓一個(gè) Mediator 直接去獲取調(diào)用其他的 Mediator,在Mediator 中定義這樣的操作本身就是錯(cuò)誤的。可以看上面的概念圖,Mediator和Mediator之間不會(huì)直接進(jìn)行通信的,這樣就違背了降低耦合性的初衷。

當(dāng)一個(gè)View的改變會(huì)影響到另外一個(gè)View組件,發(fā)送Notification通知即可

4.Proxy 是有狀態(tài)的,當(dāng)狀態(tài)發(fā)生變化時(shí)發(fā)送 Notification 通知Mediator,將數(shù)據(jù)的變化反映到視圖組件上。

將這些多次使用到的“請(qǐng)求“,通過(guò)command實(shí)現(xiàn),使之更加的獨(dú)立,提高重用性

>>>>>>>>>>>>>>>>>>>

前面提到的兩個(gè)設(shè)計(jì)模式:Proxy設(shè)計(jì)模式 和?Mediator設(shè)計(jì)模式

兩者所做的事情非常的相似,但定義上,Proxy更側(cè)重于控制數(shù)據(jù)的訪問(wèn),相當(dāng)于真實(shí)數(shù)據(jù)的代表,而Mediator則更側(cè)重于數(shù)據(jù)的交互(封裝了一系列對(duì)象的交互),強(qiáng)邏輯,比如AB之間交互的中間人,那么對(duì)于UI的交互是相對(duì)復(fù)雜繁瑣的,所以使用Mediator來(lái)負(fù)責(zé)處理View上的操作

在《大話設(shè)計(jì)模式》中舉了個(gè)蠻不錯(cuò)的例子來(lái)說(shuō)明Mediator,即聯(lián)合國(guó),類似的還有環(huán)境保護(hù)組織,我們?nèi)粘D芙佑|的房產(chǎn)中介,負(fù)責(zé)房屋的勘察,審核,買賣,繳稅,過(guò)戶等(交互,強(qiáng)邏輯)工作。

如果直接讓我們和房東聯(lián)系,很多不懂的知識(shí)外,還有法律上的風(fēng)險(xiǎn)。

另一個(gè)例子,4S店,我們買賣,售后等都要去4S店進(jìn)行處理,在Mediator中,A和B進(jìn)行交互,A和B都”認(rèn)識(shí)“Mediator中介者,我們?nèi)フ?S店,4S店負(fù)責(zé)和汽車的生產(chǎn)商溝通

>>>>>>>>>>>>>>

其實(shí)上面對(duì)應(yīng)model和proxy,view和mediator說(shuō)的已經(jīng)比較清晰了,但command和controller的關(guān)系還是比較模糊的。

事實(shí)上,Controller保存了所有Command的映射,Command 類是無(wú)狀態(tài)的,只在需要時(shí)才被創(chuàng)建。

這里使用到了Command命令設(shè)計(jì)模式,將一個(gè)“請(qǐng)求”,"行為”封裝為一個(gè)對(duì)象,將邏輯的部分進(jìn)行獨(dú)立封裝,提高復(fù)用性,對(duì)View或Mediator的修改也不會(huì)影響到Command本身。通過(guò)Facade頂層接口,可以在Proxy,Mediator,Command之間,相互訪問(wèn)和通信。

Command 可以獲取 Proxy 和Mediator對(duì)象并與之交互,發(fā)送 Notification,執(zhí)行其他的 Command。經(jīng)常用于復(fù)雜的或系統(tǒng)范圍的操作,如應(yīng)用程序的“啟動(dòng)”和“關(guān)閉”。應(yīng)用程序的業(yè)務(wù)邏輯應(yīng)該在這里實(shí)現(xiàn)。

Facade 需要在啟動(dòng)時(shí)初始化 Controller,建立 Notification 與 Command的映射。

Controller 會(huì)注冊(cè)偵聽每一個(gè) Notification,當(dāng)被通知到時(shí),Controller 會(huì)實(shí)例化一個(gè)該 Notification 對(duì)應(yīng)的 Command 類的對(duì)象。最后,將 Notification 作為參數(shù)傳遞給execute 方法。具體可以參考Command基類的實(shí)現(xiàn)。

也就是說(shuō),Command的執(zhí)行是通過(guò)發(fā)送Notification通知操作的。

Command 對(duì)象是無(wú)狀態(tài)的;只有在需要的時(shí)候( Controller 收到相應(yīng)的Notification)才會(huì)被創(chuàng)建,并且在被執(zhí)行(調(diào)用 execute 方法)之后就會(huì)被刪除。所以不要在那些生命周期長(zhǎng)的對(duì)象(long-living object)里引用 Command 對(duì)象。

在運(yùn)行中,可以通過(guò)Command來(lái)初始化Proxy和Mediator,即注冊(cè)到Facade中

比如:

public class ModelPrepCommand : SimpleCommand {

?//由 MacroCommand 調(diào)用

?public override void Execute (INotification notification) {

?IFacade.registerProxy (new SearchProxy ());

?IFacade.registerProxy (new PrefsProxy ());

?IFacade.registerProxy (new UsersProxy ());

?}

需要注意的是,?PureMVC 中有兩個(gè)類實(shí)現(xiàn)了ICommand 接口:SimpleCommand、MacroCommand。SimpleCommand 只有一個(gè) execute 方法,execute 方法接受一個(gè)Inotification 實(shí)例做為參數(shù)。實(shí)際應(yīng)用中,你只需要重寫這個(gè)方法就行了

MacroCommand 讓你可以順序執(zhí)行多個(gè) Command。每個(gè)執(zhí)行都會(huì)創(chuàng)建一個(gè) Command 對(duì)象并傳參一個(gè)對(duì)源 Notification 的引用。MacroCommand 在構(gòu)造方法調(diào)用自身的 initializeMacroCommand 方法。實(shí)際應(yīng)用中,你需重寫這個(gè)方法,調(diào)用 addSubCommand 添加子 Command。你可以任意組合 SimpleCommand 和 MacroCommand 成為一個(gè)新的 Command。

對(duì)于簡(jiǎn)單的項(xiàng)目,只需要實(shí)現(xiàn)SimpleCommand即可,它足以應(yīng)付所需要的場(chǎng)景

上面還有提到兩個(gè)概念:Business Logic(業(yè)務(wù)邏輯)和 Domain Logic(域邏輯)

在程序的很多地方你都可以放置代碼(Command,Mediator 和Proxy);不可避免地會(huì)不斷碰到一個(gè)問(wèn)題:哪些代碼應(yīng)該放在哪里?確切的說(shuō),Command 應(yīng)該做什么?

程序中的邏輯分為 Business Logic(業(yè)務(wù)邏輯)和 Domain Logic(域邏輯),首先需要知道這兩者之間的差別。

Business Logic(業(yè)務(wù)邏輯)要協(xié)調(diào) Model 與視圖狀態(tài)(View)。

Model 通過(guò)使用 Proxy 來(lái)保證數(shù)據(jù)的完整性、一致性 。Proxy 集中程序的Domain Logic(域邏輯),并對(duì)外公布操作數(shù)據(jù)對(duì)象的 API。它封裝了所有對(duì)數(shù)據(jù)模型的操作,不管數(shù)據(jù)是客戶端還是服務(wù)器端的,對(duì)程序其他部分來(lái)說(shuō)就是數(shù)據(jù)的訪問(wèn)是同步還是異步的

Mediator 和 Proxy 可以提供一些操作接口讓 Command 調(diào)用來(lái)管理 ViewComponent 和Model( Data Object),同時(shí)對(duì) Command 隱藏具體操作的細(xì)節(jié)

Observer 與 Notification ?

PureMVC的通信是使用觀察者模式以一種松耦合的方式來(lái)實(shí)現(xiàn)的,幾乎在游戲開發(fā)中,無(wú)處不在的設(shè)計(jì)模式,你只需要使用一個(gè)非常簡(jiǎn)單的方法從 Proxy,Mediator, Command 和 Facade 發(fā)送 Notification,甚至不需要?jiǎng)?chuàng)建一個(gè)Notification 實(shí)例。

Facade 和 Proxy 只能發(fā)送 Notification,Mediators 既可以發(fā)送也可以接收 Notification,Notification 被映射到 Command,同時(shí) Command 也可以發(fā)送 Notification。這是一種“發(fā)布/訂閱”機(jī)制 ,所有的觀察者都可以收到相同的通知。例如多個(gè)書刊訂閱者可以訂閱同一份雜志,當(dāng)雜志有新刊出版時(shí),所有的訂閱者都會(huì)被通知。

Facade 保存了 Command 與 Notification 之間的映射。當(dāng) Notification(通知)被發(fā)出時(shí),對(duì)應(yīng)的 Command(命令)就會(huì)自動(dòng)地由 Controller 執(zhí)行。Command 實(shí)現(xiàn)復(fù)雜的交互,降低 View 和 Model 之間的耦合性

定義Notification常量

當(dāng)這些 Notification 的名稱常量需要被其他的程序訪問(wèn)時(shí),我們可以使用單獨(dú)的“ApplicationConstants”類來(lái)存放這些 Notification 名稱常量定義。不管什么時(shí)候,都應(yīng)該把 Notification(通知)名稱定義為常量,需要引用一個(gè) Notification 時(shí)就使用它的名稱常量,這樣做可以避免一些編譯時(shí)無(wú)法發(fā)現(xiàn)的錯(cuò)誤。因?yàn)榫幾g器可以檢查常量;而使用字符串,如果你手誤輸入錯(cuò)誤的字符串,編譯器也不法知道,也無(wú)從報(bào)錯(cuò)。

Mediator發(fā)送、聲明、接收Notification

當(dāng)用 View 注冊(cè) Mediator 時(shí),Mediator 的 listNotifications 方法會(huì)被調(diào)用,以數(shù)組形式返回該 Mediator 對(duì)象所關(guān)心的所有 Notification。之后,當(dāng)系統(tǒng)其它角色發(fā)出同名的 Notification(通知)時(shí),關(guān)心這個(gè)通知的Mediator 都會(huì)調(diào)用 handleNotification 方法并將 Notification 以參數(shù)傳遞到方法

舉個(gè)例子:當(dāng)Proxy數(shù)據(jù)進(jìn)行改變時(shí),會(huì)發(fā)送通知,這里Mediator是被通知者,當(dāng)Proxy數(shù)據(jù)進(jìn)行改變時(shí),Mediator接收到通知,并對(duì)UI進(jìn)行更新

當(dāng)然它自己也可以發(fā)送通知

Proxy發(fā)送,但不接收Notification

在很多場(chǎng)合下 Proxy 需要發(fā)送 Notification(通知),比如:Proxy 從遠(yuǎn)程服務(wù)接收到數(shù)據(jù)時(shí),發(fā)送 Notification 告訴系統(tǒng);或當(dāng) Proxy 的數(shù)據(jù)被更新時(shí),發(fā)送 Notification 通知視圖組件進(jìn)行更新等等。

如果讓 Proxy 也偵聽 Notification(通知)會(huì)導(dǎo)致它和 View(視圖)層、Controller(控制)層的耦合度太高。

View 和 Controller 必須監(jiān)聽 Proxy 發(fā)送的 Notification,因?yàn)樗鼈兊穆氊?zé)是通過(guò)可視化的界面使用戶能與 Proxy 持有的數(shù)據(jù)交互。不過(guò)對(duì) View 層和 Controller 層的改變不應(yīng)該影響到 Model 層。

總結(jié)一下:

View和Model之間是單向依賴關(guān)系,View必須知道Model是什么,View也是基于Model的數(shù)據(jù)來(lái)顯示視圖上的內(nèi)容。而Model并不在乎View上的內(nèi)容。

Proxy和Mediator在職責(zé)上,均是代理,中介者的角色,負(fù)責(zé)與其它組件進(jìn)行通信。而他們的注冊(cè)都由Facade來(lái)統(tǒng)一進(jìn)行管理。

Proxy和Mediator中不應(yīng)該包含大量的業(yè)務(wù)邏輯,業(yè)務(wù)邏輯部分應(yīng)該放在Command中處理,對(duì)于數(shù)據(jù)本身的一些操作,應(yīng)該放在Proxy和Mediator中。

雖然Mediator中可以訪問(wèn)任意的Proxy,并進(jìn)行修改,但不建議這樣做,由 Command 來(lái)做這些工作可以實(shí)現(xiàn) View 和 Model 之間的松耦合。這樣Command可以被View的其它部分重用。

理論的部分分析完了,當(dāng)然還是有不明白的地方,可能在接下來(lái)的實(shí)際應(yīng)用中會(huì)得到答案。

備注:此文章僅供學(xué)習(xí)參考!












































PureMvc在CocosCreator項(xiàng)目中的應(yīng)用(一)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
通辽市| 上虞市| 玛多县| 友谊县| 定陶县| 吴川市| 孙吴县| 霞浦县| 进贤县| 丹阳市| 曲沃县| 南江县| 南阳市| 酉阳| 洛隆县| 册亨县| 舒兰市| 雷州市| 沧州市| 黄梅县| 越西县| 文安县| 汪清县| 万源市| 宝兴县| 兴山县| 佛山市| 石渠县| 铜鼓县| 独山县| 平顶山市| 和田县| 肥东县| 尼木县| 韶关市| 兴和县| 昌黎县| 哈密市| 宿迁市| 枣阳市| 天长市|