乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      亂砍設(shè)計(jì)模式之八

       wtf_soft 2006-04-18
      BRIDGE模式 —— 所謂伊人,在水一方

      junguo

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

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

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

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

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

           我們把不同風(fēng)格給分離了出來。它們有一個(gè)基類Img,主要用來實(shí)現(xiàn)基本的畫圖功能,比如畫線,畫圈等內(nèi)容(我們這邊只簡(jiǎn)單列出了畫垂直線和水平線)。而我們的場(chǎng)景也是一個(gè)單獨(dú)的類,在這些類中調(diào)用Img接口提供的基本畫圖功能來實(shí)現(xiàn)不同的圖形。抽象出來后,我們?cè)倩仡^看上面提到的問題。假如我們添加一個(gè)具體的實(shí)物進(jìn)來,比如說要添加天空進(jìn)來,那么我們只要添加一個(gè)類就好了,只要調(diào)用保證它調(diào)用Img接口來實(shí)現(xiàn)就可以有不同的風(fēng)格了。如果需要添加另一種風(fēng)格進(jìn)來,如后印象主義風(fēng)格,那我們也不需要改變?cè)械念?,只要先添加一個(gè)類進(jìn)來就好了。擴(kuò)展是不是方便了很多?還是來看看模擬的代碼(簡(jiǎn)陋了些,我只能用文字表達(dá)表達(dá)了),先來看看風(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)格的圖形,但我想將來應(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的指針,通過它來調(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)中有這樣的語句:“m_pImg = new CanvasImg()”,而且Scene類中沒有改邊m_pImg的方法,這樣做的原因是因?yàn)橐话銇碚fBridge是對(duì)于整個(gè)程序風(fēng)格的設(shè)置。你配置了什么樣的風(fēng)格,整個(gè)程序運(yùn)行的過程中風(fēng)格就是什么。因?yàn)橐话銇碚fBridge主要是適用于跨平臺(tái)的開發(fā),在Linux中與在Windows中,畫圖的方法肯定不相同,通過Bridege可以解決這個(gè)問題,但在運(yùn)行過程中肯定不應(yīng)該改變Bridge的類型。可以通過配置文件來實(shí)現(xiàn),這樣的話,在m_pImg生成的地方通過讀取配置文件,根據(jù)文件類型來創(chuàng)建m_pImg就好了。當(dāng)然你想在運(yùn)行過程中改變m_pImg類型也可以,看具體情況了。再看看調(diào)用:
      int main(int argc, char* argv[])
      {
      Hill h;
      Water w;
      h.DrawBorder();
      w.DrawBorder();
      return 0;
      }
      

          通過創(chuàng)建的Hill或者Water類去畫圖就可以了。
          我們?cè)賮砜纯碆ridge的定義:將抽象部分和它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化。其實(shí)這里的抽象用的并不貼切,但想不到太好的詞,人類語言的表達(dá)能力是有限的。這里所說的抽象,并不是我們所說的接口的抽象。在例子里抽象指的就是Img及其子類了,用來畫圖的對(duì)象。而實(shí)現(xiàn)部分指的就是我們的Hill和Water類了。
          Bridge看完了,是不是感覺有些眼熟呢?你是不是和我一樣遲鈍,想半天,還需要翻看書才想起來?回憶一下我們之前談過的策略模式,看看類圖。兩個(gè)模式不僅相似,而且相似的令人發(fā)指,完全是一樣的。但為什么會(huì)被劃成兩個(gè)模式呢?其實(shí)主要是它們要解決的問題不相同,策略模式針對(duì)的是類中所屬的單個(gè)對(duì)象或者單個(gè)方法,由于這樣的對(duì)象或者方法會(huì)有不同的實(shí)現(xiàn)方法,可能需要運(yùn)行時(shí)刻動(dòng)態(tà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)蒙古出版社
      

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多