<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      重溫設(shè)計模式(六)—— 階段總結(jié)一

       1. 寫在前面的

      在文章開始之前,先寫一些廢話,不知不覺把重溫設(shè)計模式寫完了五篇。

      <1> 重溫設(shè)計模式(一)——享元模式(Flyweight) 

      <2> 重溫設(shè)計模式(二)——橋接模式(Bridge)

      <3> 重溫設(shè)計模式(三)——職責鏈模式(chain of responsibility)

      <4> 重溫設(shè)計模式(四)——工廠模式

      <5> 重溫設(shè)計模式(五)——我所理解的"抽象工廠"

      下面的文章,算是對以上五篇文章的一個階段性總結(jié)和反省。

      首先,我得特別感謝winter-cn不厭其煩地指出我在設(shè)計模式應(yīng)用中的一個又一個錯誤,如果沒有他,很多東西我還是會繼續(xù)地錯下去。

      另外,也感謝博客園眾多園友對我的鼓勵,讓我有勇氣再次寫下去。

      2. 步入正題1——享元模式

      享元模式運用共享技術(shù)有效地支持了大量細粒度的對象,解決了大量對象造成的內(nèi)存開銷問題。

      何時采用享元模式:

      在這里我補充兩個很重要的概念:內(nèi)蘊狀態(tài)和外蘊狀態(tài)。內(nèi)蘊狀態(tài)是共享對象中被所有對象所共享的東西,而外蘊狀態(tài)是由外部調(diào)用者傳進去的東西。

      我們這里就借助Word文檔的例子來說明這兩個概念,轉(zhuǎn)了一圈,再次回到GOF:

      在一篇文章中,一共只有26個字母,但是這篇文章卻可能有幾萬個字。那么這個時候,我們就可以用享元模式來解決問題。 

      這個時候什么是內(nèi)蘊狀態(tài)?什么是外蘊狀態(tài)?

      內(nèi)蘊狀態(tài)被所有調(diào)用者所共享,也就是那26個字母。

      而外蘊狀態(tài)呢?就是每個字符所不可能不同的字體。看清楚,是可能不同。

      如果寫成示例代碼:

      class Character
      {
          char c;
          Font f;
          private List<Font> fontList;
      
          public Font F
          {
              set
              {
                  int i = 0;
                  for (i = 0; i < fontList.Count; i++)
                  {
                      if (fontList[i].Equals(value))
                      {
                          this.f = fontList[i];
                          break;
                      }
                  }
                  fontList.Add(value);
                  f = value;
              }
          }  
      }
      class Font
      {
          string fontName;
          string color;
          int size;
          // and so on;
      }

      3. 享元模式——原文反思

      在我的原文重溫設(shè)計模式(一)——享元模式(Flyweight) 中,我錯在了哪?

      回到我QQ聊天的那個例子:

      在Chat對象中,我有三個字段,string boyName,string girlName,string content。

      在文中,我將boyName+ _ +girlName作為了內(nèi)蘊狀態(tài),而將content作為了外蘊狀態(tài)。

      這個從表面上來看沒有錯,但是實際錯在哪里?

      在享元模式的使用條件中有著這樣一條:如果刪除對象的外蘊狀態(tài),那么可以用相對較少的共享對象去取代很多組對象,此時可以考慮享元模式。

      先結(jié)合GOF26個字母的那個例子來分析這句話:26個字母,也就是26組,每個字母可能有著不同的字體,于是也就是每組又有著若干個對象,如果我們把字體這個外蘊條件刪除,那么這26組就可以用26個對象去表示。

      好了,來看我的例子: boyName+_+girlName作為內(nèi)蘊狀態(tài):這個我認為并無錯誤,雖然在GOF的模式例子中,26個組可以說是已經(jīng)搞定好的,但是我在QQ聊天的這個例子中,動態(tài)地去添加組,我認為這點并無不可。

      這個項目的問題在于外蘊狀態(tài),我們知道每一次和每一次的聊天內(nèi)容,也就是content是不同的,我把這個content去作為外蘊狀態(tài),本身就沒有共享,重利用的意義。

      繼續(xù)用上面那個組的概念去說話。假設(shè)現(xiàn)在有100對男女在聊天,那么根據(jù)boyName+_+girlName,可以把所有對象分成100組,由于這每組對象的content是不同的,也就是每次回發(fā)給服務(wù)器時,這個content都無法被重利用,所以說100組對象,共有100個對象,而這個100個對象,把外蘊狀態(tài)剔除掉,還是100個對象。

      因此說,這個例子是不適合享元模式的。

      4. 享元模式——垂死掙扎(享元模式究竟享什么?)

      此處聲明,此處為垂死掙扎區(qū),所以這里只是個人意見,純屬扯淡,請初學(xué)者選擇性相信。理解有誤,希望各位指教。

      究竟什么是享元模式,享元模式無非就是通過共享技術(shù)去支持大量大粒度對象,使存儲開銷減小。

      還是考慮原文中String的應(yīng)用,這是個標準的享元模式,我想這點無人質(zhì)疑。那么我們看String共享的是什么?String對象,內(nèi)蘊狀態(tài)是這個字符串的值,那么外蘊狀態(tài)呢?其實就是他所指向的地址。

      我們先用享元模式去實現(xiàn)String。

      class String1
      {
          string content;
          string address;
          private List<string> stringList;
      
          public string Address
          {
              set
              {
                  int i = 0;
                  for (i = 0; i < stringList.Count; i++)
                  {
                      if (stringList[i].Equals(value))
                      {
                          this.address = stringList[i];
                          break;
                      }
                  }
                  stringList.Add(value);
                  address = value;
              }
          }
      }

      的確,每一個content都對應(yīng)了一個address,而且共享了address。但我們想一下,若干個相同的content對應(yīng)的是不是同一個address呢?也就是說,當content固定下來,他的address也就隨之固定了下來。

      與其這樣,那我們還不如這樣去寫:Dictionary<string,string> dic=new Dictionary<string,string>();dic.Add(content,address)。

      這又何樂而不為呢?

      所以說,我認為,享元模式本身是一個宏觀概念。享的什么不重要,總之,目的只有一個,節(jié)省內(nèi)存。至此而已!

      5. 步入正題2——橋接模式

      橋接模式, GOF這樣去解釋他:將抽象部分和實現(xiàn)部分分離,使他們都可以獨立地變化。

      我個人認為這個是組合優(yōu)于繼承設(shè)計原則的一個很棒的體現(xiàn)。

      6. 橋接模式 —— 原文反思

      我的例子是不是橋接模式?很明確的,不是!

      這里就要提到一個概念的解釋。GOF說,講抽象和實現(xiàn)部分相分離。這里的實現(xiàn)是什么意思?

      這個實現(xiàn)并非是我們平時說的“實現(xiàn)”某一接口的實現(xiàn)。而是可以這樣解釋:

      對于同樣一個Work()方法來說,對于程序員來說,Work是編程,對于工人來說,是操作機器,對于教師來說,是教書。

      代碼如下:

      interface IWork
      {
          void Work();
      }
      
      class Programer : IWork
      {
      
          #region IWork 成員
      
          public void Work()
          {
              Console.WriteLine("寫代碼");
          }
      
          #endregion
      }
      class Teacher : IWork
      {
      
          #region IWork 成員
      
          public void Work()
          {
              Console.WriteLine("教書");
          }
      
          #endregion
      }

      然后將這個具體的實現(xiàn)注入到我們的應(yīng)用類中,如在上文中的注入方式極為SetWork(IWork work){};

      那么我原文中,Photoshop的例子錯在哪里?

      我錯在了對實現(xiàn)的錯誤理解上,因此我的例子只是一個單純的組合優(yōu)于繼承。

      也就是說,橋接模式只是組合優(yōu)于繼承的一個應(yīng)用,但是并非等于組合優(yōu)于繼承。橋接模式本身的目的解決的是由于實現(xiàn)而帶來的類爆炸問題。

      7. 橋接模式——絕地反擊winter-cn(橋接模式只有一個橋么?)

      再次聲明,此處為絕地反擊區(qū),所以這里只是個人意見,純屬扯淡,請初學(xué)者選擇性相信。理解有誤,希望各位指教。

       

      這樣可否呢?

      舉個例子:我們要做Windows和Linux,Windows和Linux下的QQ游戲?qū)崿F(xiàn)是不同的,Windows和Linux下的記事本實現(xiàn)是不同的,Windows和Linux下的*****實現(xiàn)是不同的,那么他們就應(yīng)該都分別抽出來形成一個橋。

      然后我們原本的代碼是:

      class Program
      {
          private Implementor i;
          public void SetImplementor(Implementor i)
          {
              this.i = i;
          }
          public void Run()
          {
              i.Run();
          }
      }
      
      abstract class Implementor
      {
          public abstract void Run();
      }

      但是我們在此處就如此實現(xiàn):

      class Program
      {
          private Implementor1 i1;
          private Implementor2 i2;
          private Implementor3 i3;
          public void SetImplementor(Implementor1 i1,Implementor2 i2,Implementor3 i3)
          {
              this.i1 = i1;
              this.i2 = i2;
              this.i3 = i3;
          }
          public void Run1()
          {
              i1.Run();
          }
          public void Run2()
          {
              i2.Run();
          }
          public void Run3()
          {
              i3.Run();
          }
      }
      
      abstract class Implementor1
      {
          public abstract void Run();
      }
      abstract class Implementor2
      {
          public abstract void Run();
      }
      abstract class Implementor3
      {
          public abstract void Run();
      }

       

      這本就合情合理,每個人家門前可以根據(jù)自己的需求去建橋,又何必去規(guī)定每家門前只有一座橋呢?

      另外,大家可以把重溫設(shè)計模式(二)——橋接模式(Bridge)當作重溫設(shè)計模式(二)——組合優(yōu)于繼承去理解,也會是一篇好文哦!

      8.  補充說明——職責鏈模式

      關(guān)于職責連模式,在這里我只是想補充一點:關(guān)于職責鏈和鏈表的區(qū)別。

      在文中,我提到了職責鏈和鏈表的區(qū)別,在這里加以補充。

      最近我在寫一個關(guān)于工作流的入門文章,我們知道,工作流分為順序工作流和狀態(tài)機工作流。工作流其實就是一種復(fù)雜模式下的,有成熟框架,有圖形化表示的職責鏈。

      那么當然,職責鏈按理來說也是應(yīng)該支持狀態(tài)機的。

      我在這里引用一個我畫的關(guān)于狀態(tài)機工作流的圖:

       

      也就是說,在狀態(tài)機中,可以出現(xiàn)A.Next=b;b.Next=a;的情況,但是在鏈表中就絕對不會出現(xiàn)這種情況。

      原因在于,一個職責鏈的每一個節(jié)點,可以引出多個Next指針,關(guān)于這點,大家可以參考我原文中的職責鏈的擴展——樹狀鏈結(jié)構(gòu)。

      9.  再說工廠

      在這里,我只是想針對我的原文進行一個再說明。

      首先是我在測試代碼中,乃至全文都說的無模式。 那個無模式真的是無模式么?其實,我們更應(yīng)該將他理解為一個偽工廠。工廠究竟是來做什么的?

      這個從抽象談起,我們在設(shè)計軟件的時候,在設(shè)計的就是那么一個抽象。而這個工廠的Create,其實就是對創(chuàng)建對象的一個抽象化。

      那么我所謂的無模式,其實也是將這個創(chuàng)建產(chǎn)品的過程給單獨地提取抽象了出來。可以說是一個簡化版的工廠,或者是簡化版的簡單工廠。

      這個無模式有個什么樣的局限性呢?當我們有一個產(chǎn)品,既用了ProductA,也用了ProductB,而且這種情況是非常常見的。

      那么這個時候,我的簡化版“偽”工廠就無法實現(xiàn)需求了。

      總之,什么樣的設(shè)計取決于什么樣的變化!

      10. 步入正題3——抽象工廠

      抽象工廠解決的問題是一個產(chǎn)品族的問題。

      什么是產(chǎn)品族,我之前的解釋有些問題。產(chǎn)品族不是可以隨意搭配的。抽象工廠僅提供有效的組合,而對于隨意的組合就不是抽象工廠所能解決問題的范疇。

      11.  抽象工廠——原文反思

      在原文中,我舉到了一個汽車的例子,那個例子就不是一個抽象工廠所能解決范圍之內(nèi)的例子。

      回到我們之前的隨意組合和有效組合的問題。

      油漆的顏色,與發(fā)動機的引擎,再到輪子的型號,這三者之間是沒有一個互相約束的聯(lián)系的。也就是說,無論什么顏色的油漆,都可以配任意型號的引擎。也就是說如果有3種油漆,4種引擎,那么就有3*4=12種搭配,這個就叫做隨意組合,是不可以用抽象工廠來解決的。

      比如這樣的例子就很合理了,操作系統(tǒng)和應(yīng)用軟件的關(guān)系,比如現(xiàn)在有兩種系統(tǒng),Windows,Linux,有三種應(yīng)用軟件:QQ,Office,***(比如這個是只能在Linux上運行的),那么他們之間就只有Windows+QQ,Linux+QQ,Windows+Office,Linux+****4種組合,這樣我們就把他叫做有效組合,而非隨意組合,這個才是抽象工廠解決的范疇。

      12.  抽象工廠—— 垂死掙扎

      排除我的原文中,CPU和顯卡例子不合理外,各位可以參考我在其他例子及章節(jié)處,個人感覺觀點不無道理。

      13. 總結(jié)

      很多問題,很多模式,也許我們現(xiàn)在并不常用,拿當前的C#,Java等語言來說,他們可以為我們做太多的事情。

      例如說,迭代器模式,觀察者模式,這些在C#中都被簡化了許多許多,甚至已經(jīng)快廢棄掉了。

      但是我們學(xué)習(xí)模式學(xué)習(xí)的是一種設(shè)計思路,一種思維,首先,我們可以拋去那些高級特性,只去單純地想面向?qū)ο蟆?/font>

      然后我們可以去想著,用當今的語言特性(如C#),我們可以如何去改進這個設(shè)計模式,我們在實際應(yīng)用中,如何去用模式+模式去更好地利用這個模式。

      最后,說個事:

       

      TerryLee的排名超過的園長dudu……………………

       

       

      posted @ 2009-04-15 04:20  飛林沙  閱讀(3378)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 东京热人妻中文无码| 免费a级毛片18以上观看精品| 久久精品国产一区二区三| 日韩在线观看精品亚洲| 伊人av超碰伊人久久久| 精品久久久无码人妻中文字幕| 99在线国内在线视频22| 亚洲国产美女精品久久久 | 内射老阿姨1区2区3区4区| 久久久亚洲欧洲日产国码αv| 厨房与子乱在线观看| 国产小受被做到哭咬床单GV| 艳妇乳肉豪妇荡乳av| 亚洲国产精品色一区二区| 亚洲精品一区三区三区在| 精品国产午夜福利在线观看| 亚洲av无码之国产精品网址蜜芽 | 国产精品久久无码不卡黑寡妇| 日本韩国日韩少妇熟女少妇| 国产av一区二区午夜福利| 性欧美VIDEOFREE高清大喷水| 丰满人妻一区二区三区无码AV| 狠狠亚洲丁香综合久久| 亚洲国产精品综合久久20| 日韩精品无码去免费专区| 久久精品一本到99热免费| 国产露脸无套对白在线播放| 亚洲第一天堂无码专区| 日韩精品无遮挡在线观看| 国产精品国产高清国产av| 毛片网站在线观看| 久久综合老鸭窝色综合久久| 蜜桃视频在线免费观看一区二区| 高潮潮喷奶水飞溅视频无码| 无码AV中文字幕久久专区| 天堂中文8资源在线8| 男人下部进女人下部视频| 日本丶国产丶欧美色综合 | 日本中文字幕有码在线视频| jizz国产免费观看| 中文字幕亚洲综合久久 |