免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
亂砍設(shè)計(jì)模式之八
BRIDGE模式 —— 所謂伊人,在水一方

junguo

     Bridge模式的中文名稱是橋接模式,該模式的目的是將抽象部分和它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化。繼續(xù)以例子來(lái)完成對(duì)該模式的學(xué)習(xí)。

     蒹葭蒼蒼,白露為霜。所謂伊人,在水一方。
     溯洄從之,道阻且長(zhǎng)。溯游從之,宛在水中央。
    
     蒹葭凄凄,白露未晞。所謂伊人,在水之湄。
     溯洄從之,道阻且濟(jì)。溯游從之,宛在水中坻。
    
     蒹葭采采,白露未已。所謂伊人,在水之涘。
     溯洄從之,道阻且右。溯游從之,宛在水中沚。

     這首《蒹葭》取自《詩(shī)經(jīng)》。王國(guó)維在他的《人間詞話》中評(píng)述說(shuō):“《詩(shī)?蒹葭》一篇,最得風(fēng)人深致”。簡(jiǎn)單的場(chǎng)景切換,最直接的感情描寫,成了千百年來(lái)最能體現(xiàn)詩(shī)人情致的詩(shī)。我感覺(jué)詩(shī)在形式上最重要的是它的語(yǔ)言,簡(jiǎn)單凝練是真正的境界?,F(xiàn)今的白話詩(shī),大多被寫的晦澀難懂,讀完后佩服詩(shī)人到無(wú)話可說(shuō),寫的字都認(rèn)識(shí),但是就不明白放到一塊是什么意思。一直搞不懂為什么要寫成那樣?白話文寫的詩(shī)歌比古文都難懂很多,有人說(shuō)這是一個(gè)不需要詩(shī)人的時(shí)代,但我想也許是詩(shī)人漂離了時(shí)代,他們也許走到了時(shí)代的前列,但我又覺(jué)得不見(jiàn)得過(guò)多少年后就會(huì)有人愿意花時(shí)間去琢磨晦澀的東西。除了形,就是意了。詩(shī)歌在意上追求境界,應(yīng)該給人遐想的空間。如“有的人死了,他還活著;有的人活者,他已經(jīng)死了”直白到無(wú)任何情趣的詩(shī),也讓人毫無(wú)興趣;但這樣的詩(shī)一度是中國(guó)詩(shī)的主流,而穆旦那樣的優(yōu)秀詩(shī)人則被排擠出了主流,排擠到無(wú)法繼續(xù)寫詩(shī)的地步。繼續(xù)說(shuō)《蒹葭》,讀完詩(shī)歌會(huì)感覺(jué)到這樣一個(gè)場(chǎng)景,青山綠水,遠(yuǎn)處隱隱約約一個(gè)少女的身影。近處一個(gè)男子在急切的尋找著船只,眺望著遠(yuǎn)方的路。而他最終沒(méi)找到船,望不到路,焦慮憂傷盡顯臉上。也許你會(huì)和我一樣發(fā)現(xiàn),這個(gè)尋路人就是自己。我在想程序是否也有境界,這個(gè)境界又該有什么樣樣的標(biāo)準(zhǔn)呢?
     這樣的詩(shī)歌意境也許可以做成一款游戲。記得上學(xué)的時(shí)候有款游戲《心跳回憶》,類似于養(yǎng)成游戲,游戲的內(nèi)容就是玩家通過(guò)不斷的邀請(qǐng)游戲中的美女約會(huì),送禮物給美女等方式來(lái)增加美女對(duì)玩家的好感,好感增加到一定程度,她就會(huì)接受玩家的求婚。很少有人有耐心玩完這款破游戲,但我們同學(xué)中有位仁兄樂(lè)此不疲??荚嚽皫讉€(gè)鐘頭還在玩,結(jié)果考后掛了幾科要降級(jí)了。當(dāng)?shù)弥导?jí)的噩耗的時(shí)候,哥們掉了幾顆眼淚,狠狠心又坐到了電腦面前,繼續(xù)他的《心跳回憶》,10多個(gè)小時(shí)過(guò)后,當(dāng)大家還都在夢(mèng)鄉(xiāng)的時(shí)候。他就各個(gè)宿舍游蕩,看到有人醒來(lái)就異常興奮得告訴人家,《心跳回憶》中的女主角他又追到了一個(gè)。降級(jí)的郁悶就這樣被掃空了?,F(xiàn)在,聽說(shuō)這位兄弟找到的女朋友很漂亮??吹饺允菃紊淼耐瑢W(xué),也許他該竊笑了:得虧哥們當(dāng)年還練過(guò)。
     我們要實(shí)現(xiàn)的功能沒(méi)有那么復(fù)雜了,此處主要是設(shè)想幫游戲設(shè)計(jì)一個(gè)場(chǎng)景,把青山綠水畫到屏幕上。由于山可能不只一座,水也可能有多處。我們想把它們封裝成單獨(dú)的類,由客戶隨意去組合,組合成不同形狀的圖景。那么我們的類圖可以提煉成如下的形式:

     有了類圖,我們就可以進(jìn)行開發(fā)了。一般來(lái)說(shuō),游戲開發(fā)的圖景是寫實(shí)性質(zhì)的,類似于西方油畫。但經(jīng)調(diào)查發(fā)現(xiàn),有這么一幫書呆子,聽到“書中自有顏如玉”的古訓(xùn)后,遍翻古書尋找美女,后來(lái)發(fā)現(xiàn)不過(guò)癮,想到游戲中尋找自己的夢(mèng)中情人。這批人酷愛(ài)中國(guó)古典文化,重意不重形,喜歡國(guó)畫上的美女,當(dāng)然山水也應(yīng)該傳統(tǒng)的水墨畫。為了吸引這批呆子,決定在游戲中提供水墨畫的場(chǎng)景。這樣我們的類也需要進(jìn)行相應(yīng)的變化,它需要支持油畫和水墨兩種風(fēng)格。想想,我們?cè)撊绾螌?shí)現(xiàn)這一功能呢?最直接想到的就是通過(guò)繼承來(lái)實(shí)現(xiàn),那么我們的類圖可能變成這樣。

     圖中我們幫油畫和水墨都提供了接口,而山水則分別通過(guò)油畫和水墨來(lái)繼承。這樣明顯的問(wèn)題是,我們需要為山水各提供兩套代碼。有這個(gè)必要嗎?只是造圖風(fēng)格上不同,但過(guò)程是一樣的。接著想,如果我們新添加一個(gè)新場(chǎng)景進(jìn)來(lái),比如說(shuō)天空和陸地,也需要單獨(dú)的類來(lái)實(shí)現(xiàn)。那么這時(shí)候我們又要為每個(gè)場(chǎng)景添加兩個(gè)類。接著想,后來(lái)發(fā)現(xiàn),有哥們喜歡后印象主義畫派,還有哥們喜歡抽象主義(寫完后,想想了,發(fā)現(xiàn)抽象主義還是比較容易實(shí)現(xiàn)的,畫個(gè)三角形代表山,畫兩個(gè)弧線代表水,只要顏色取絢了就是抽象作品了),那么再把這些風(fēng)格都加入到該模式中,會(huì)發(fā)生什么情形呢?完了,已經(jīng)實(shí)現(xiàn)過(guò)的山水類都需要重新實(shí)現(xiàn)一次。接著想,客戶端調(diào)用又會(huì)有什么情形呢?好多類啊,該選哪個(gè)呢?當(dāng)然你也可以幫他實(shí)現(xiàn)一個(gè)抽象工廠來(lái)減輕負(fù)擔(dān),但這個(gè)工廠的實(shí)現(xiàn)一樣煩瑣。看到了這么多問(wèn)題,其實(shí)總結(jié)起來(lái)原因就是一個(gè),通過(guò)繼承我們把風(fēng)格和具體的實(shí)物(山,水等)固定到了一起,無(wú)法抽離出來(lái),導(dǎo)致了類的膨脹。那么該如何解決這個(gè)問(wèn)題呢?方法就是把這兩樣?xùn)|西給分離出來(lái),讓它們各自實(shí)現(xiàn)各自的代碼。怎么實(shí)現(xiàn)呢?來(lái)看類圖:

     我們把不同風(fēng)格給分離了出來(lái)。它們有一個(gè)基類Img,主要用來(lái)實(shí)現(xiàn)基本的畫圖功能,比如畫線,畫圈等內(nèi)容(我們這邊只簡(jiǎn)單列出了畫垂直線和水平線)。而我們的場(chǎng)景也是一個(gè)單獨(dú)的類,在這些類中調(diào)用Img接口提供的基本畫圖功能來(lái)實(shí)現(xiàn)不同的圖形。抽象出來(lái)后,我們?cè)倩仡^看上面提到的問(wèn)題。假如我們添加一個(gè)具體的實(shí)物進(jìn)來(lái),比如說(shuō)要添加天空進(jìn)來(lái),那么我們只要添加一個(gè)類就好了,只要調(diào)用保證它調(diào)用Img接口來(lái)實(shí)現(xiàn)就可以有不同的風(fēng)格了。如果需要添加另一種風(fēng)格進(jìn)來(lái),如后印象主義風(fēng)格,那我們也不需要改變?cè)械念?,只要先添加一個(gè)類進(jìn)來(lái)就好了。擴(kuò)展是不是方便了很多?還是來(lái)看看模擬的代碼(簡(jiǎn)陋了些,我只能用文字表達(dá)表達(dá)了),先來(lái)看看風(fēng)格類所需要的代碼:
//風(fēng)格接口class Img{public://畫水平線virtual void DrawHorLine() = 0;//畫垂直線virtual void DrawVerLine() = 0;protected:Img(){}};//中國(guó)畫風(fēng)格class ChineseImg : public Img{public:void DrawHorLine(){cout << "水墨畫水平線" << endl;}void DrawVerLine(){cout << "水墨畫垂直線" << endl;}};//油畫風(fēng)格class CanvasImg : public Img{public:void DrawHorLine(){cout << "油畫水平線" << endl;}void DrawVerLine(){cout << "油畫垂直線" << endl;}};

    這邊要實(shí)現(xiàn)的功能其實(shí)就是提供畫圖的基本方法,比如畫線或者畫圓等動(dòng)作(我不太清楚,現(xiàn)在圖形庫(kù)能不能幫我們實(shí)現(xiàn)水墨畫風(fēng)格的圖形,但我想將來(lái)應(yīng)該可以的)。我們這里的代碼比較簡(jiǎn)單,不做太多的解釋。接著看看實(shí)體類的實(shí)現(xiàn)。
//場(chǎng)景抽象類class Scene{public:virtual void DrawBorder() = 0;Img *GetImg(){return m_pImg;}virtual ~Scene(){delete m_pImg;}protected:Scene(){//此處的原因,文章里分析m_pImg = new CanvasImg();}private://擁有一個(gè)Img的指針,通過(guò)它來(lái)調(diào)用畫圖功能Img *m_pImg;};//山的類class Hill : public Scene{public:void DrawBorder(){DrawHill();}void DrawHill(){cout << "三條垂直線就代表山了!" << endl;Img *pImg = GetImg();pImg->DrawVerLine();pImg->DrawVerLine();pImg->DrawVerLine();}};//水的類class Water : public Scene{public:void DrawBorder(){DrawWater();}void DrawWater(){cout << "三條水平線就代表水了!" << endl;Img *pImg = GetImg();pImg->DrawVerLine();pImg->DrawVerLine();pImg->DrawVerLine();}};

     首先注意到一點(diǎn),就是Scene的構(gòu)造函數(shù)的實(shí)現(xiàn)中有這樣的語(yǔ)句:“m_pImg = new CanvasImg()”,而且Scene類中沒(méi)有改邊m_pImg的方法,這樣做的原因是因?yàn)橐话銇?lái)說(shuō)Bridge是對(duì)于整個(gè)程序風(fēng)格的設(shè)置。你配置了什么樣的風(fēng)格,整個(gè)程序運(yùn)行的過(guò)程中風(fēng)格就是什么。因?yàn)橐话銇?lái)說(shuō)Bridge主要是適用于跨平臺(tái)的開發(fā),在Linux中與在Windows中,畫圖的方法肯定不相同,通過(guò)Bridege可以解決這個(gè)問(wèn)題,但在運(yùn)行過(guò)程中肯定不應(yīng)該改變Bridge的類型。可以通過(guò)配置文件來(lái)實(shí)現(xiàn),這樣的話,在m_pImg生成的地方通過(guò)讀取配置文件,根據(jù)文件類型來(lái)創(chuàng)建m_pImg就好了。當(dāng)然你想在運(yùn)行過(guò)程中改變m_pImg類型也可以,看具體情況了。再看看調(diào)用:
int main(int argc, char* argv[]){Hill h;Water w;h.DrawBorder();w.DrawBorder();return 0;}

    通過(guò)創(chuàng)建的Hill或者Water類去畫圖就可以了。
    我們?cè)賮?lái)看看Bridge的定義:將抽象部分和它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化。其實(shí)這里的抽象用的并不貼切,但想不到太好的詞,人類語(yǔ)言的表達(dá)能力是有限的。這里所說(shuō)的抽象,并不是我們所說(shuō)的接口的抽象。在例子里抽象指的就是Img及其子類了,用來(lái)畫圖的對(duì)象。而實(shí)現(xiàn)部分指的就是我們的Hill和Water類了。
    Bridge看完了,是不是感覺(jué)有些眼熟呢?你是不是和我一樣遲鈍,想半天,還需要翻看書才想起來(lái)?回憶一下我們之前談過(guò)的策略模式,看看類圖。兩個(gè)模式不僅相似,而且相似的令人發(fā)指,完全是一樣的。但為什么會(huì)被劃成兩個(gè)模式呢?其實(shí)主要是它們要解決的問(wèn)題不相同,策略模式針對(duì)的是類中所屬的單個(gè)對(duì)象或者單個(gè)方法,由于這樣的對(duì)象或者方法會(huì)有不同的實(shí)現(xiàn)方法,可能需要運(yùn)行時(shí)刻動(dòng)態(tài)改變。那么我們可以用策略模式來(lái)改變這樣的功能。而Bridge針對(duì)的是整個(gè)類,根據(jù)不同的Bridge,整個(gè)類的風(fēng)格將發(fā)生變化。也可以這樣理解策略模式針對(duì)的是類中單個(gè)對(duì)象,這個(gè)對(duì)象可能影響到類中少數(shù)的幾個(gè)函數(shù)。而Bridge模式,將影響到類中決大多數(shù)的方法。
參考書目:1,	設(shè)計(jì)模式——可復(fù)用面向?qū)ο筌浖幕A(chǔ)(Design Patterns ——Elements of Reusable Object-Oriented Software) Erich Gamma 等著 李英軍等譯  機(jī)械工業(yè)出版社2,	Head First Design Patterns(影印版)Freeman等著 東南大學(xué)出版社3,	道法自然——面向?qū)ο髮?shí)踐指南    王詠武 王詠剛著  電子工業(yè)出版社4,      人間詞話手稿本      王國(guó)維 著 吳洋注釋 內(nèi)蒙古出版社
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
231 f0708
統(tǒng)計(jì)對(duì)象
使用lambda,遠(yuǎn)離bind
構(gòu)造函數(shù) 析構(gòu)函數(shù) 拷貝構(gòu)造函數(shù) this指針的使用
使用Opencv,大恒C++ SDK采集大恒水星相機(jī)圖像
收藏: C 運(yùn)算符重載 轉(zhuǎn)換函數(shù) - flyingfish - 博客園
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服