2009年10月14日

          1.1 BUILDER生成器

          1、 意圖

          將一個復(fù)雜對象的構(gòu)建和它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

          構(gòu)建是通過對生成器抽象接口的調(diào)用實現(xiàn)的。而構(gòu)建出來的產(chǎn)品的類型(表示),是由具體的進行構(gòu)建的生成器的子類的實例來決定的。這樣導(dǎo)向器只需要調(diào)用生成器的抽象接口生成產(chǎn)品,而具體生成什么樣的產(chǎn)品,則是根據(jù)導(dǎo)向器配置的具體的生成器實例相關(guān)。

          終于理解了它是如何把復(fù)雜對象的構(gòu)建和它的表示分離的,也理解了為什么同樣的構(gòu)建過程。

          2、 動機

          3、 適用性

          當創(chuàng)建復(fù)雜對象的算法應(yīng)該獨立于該對象的組成以及他們的裝配方式時——對象的組成及裝配方式是生成器的抽象接口來表示的。而對象的創(chuàng)建的算法是有生成器的子類實現(xiàn)的。

          當構(gòu)造過程必須允許被構(gòu)造的對象有不同的表示時——也就是,同樣的構(gòu)造過程,可以生成不同的產(chǎn)品。這里是通過配置導(dǎo)向器的生成器的子類實例來實現(xiàn)的。

          4、 結(jié)構(gòu)

          wps_clip_image-372

          5、 參與者

          l Builder:為創(chuàng)建一個product對象的各個部件指定抽象接口。這些部件最終構(gòu)成了product,而對這些抽象接口的調(diào)用,則是裝配product的操作,調(diào)用的次數(shù),入?yún)⒌炔煌瑒t最終生成的product也不同。product本身的構(gòu)造過程可能會非常復(fù)雜。但是,這些復(fù)雜度對Director(導(dǎo)向者)是隱藏的。這些抽象的接口描述了產(chǎn)品的組成以及裝配方式。

          l ConcreteBuilder:實現(xiàn)Builder的接口以構(gòu)造和裝配產(chǎn)品的各個部件;定義并明確它所創(chuàng)建的表示;提供一個檢索產(chǎn)品的接口。這個類實現(xiàn)了Builder的抽象接口,從而可以創(chuàng)建不同的表示,但是組成和裝配過程還是一樣的。

          l Director:構(gòu)造一個使用Builder抽象接口的對象。更對象根據(jù)Builder的接口來裝配并生產(chǎn)產(chǎn)品。

          l Product:表示被構(gòu)造的復(fù)雜的對象。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示,并定義它的裝配過程;包含定義組成部件的類,包括將這些部件裝配成最終產(chǎn)品的接口。

          6、 協(xié)作

          l 客戶創(chuàng)建Director對象,并用它想要的Builder對象進行配置。

          l 一旦產(chǎn)品不僅被生成,導(dǎo)向器就會通知生成器。

          l 生成器處理導(dǎo)向器請求,并且將部件添加到該產(chǎn)品中。

          l 客戶從生成器中檢索產(chǎn)品。

          wps_clip_image-911

          7、 效果

          l 它使你可以改變一個產(chǎn)品的內(nèi)部表示。Builder提供給Director的抽象接口可以使生成器隱藏這個產(chǎn)品的表示和內(nèi)部結(jié)構(gòu)。它同時也隱藏了該產(chǎn)品時如何裝配的。因為產(chǎn)品時通過抽象接口構(gòu)造的,你改變該產(chǎn)品的內(nèi)部表示時,所要做的只是定義一個新的生成器。

          l 它將構(gòu)造代碼和表示代碼分開。Builder模式通過封裝一個復(fù)雜對象的創(chuàng)建和表示方式提高了對象的模塊性。每個ConcreteBuilder包含了創(chuàng)建和裝配一個特定產(chǎn)品的所有代碼。

          l 它可以使你對構(gòu)造過程進行更精細的控制。

          8、 實現(xiàn)

          l 通常一個抽象的Builder類為導(dǎo)向者可能要求創(chuàng)建的每一個構(gòu)件定義一個操作。這些操作缺省什么也不做。一個ConcreteBuilder類對它有興趣創(chuàng)建的構(gòu)建重定義這些操作。

          l 裝配和構(gòu)造接口:一般構(gòu)造請求的結(jié)果只是被添加到產(chǎn)品中,特殊情況下,需要返回給導(dǎo)向器。

          l 產(chǎn)品沒有抽象類:一般他們沒有公共的部分。如果有也可以設(shè)置一個抽象類。

          l Builder中缺省的方法為空。

          9、 代碼示例

          class MazeBuilder {

          public:

              virtual void BuildMaze() { }//部件的構(gòu)造方法

              virtual void BuildRoom(int room) { }

              virtual void BuildDoor(int roomFrom, int roomTo) { }

              virtual Maze* GetMaze() { return 0; }

          protected:

              MazeBuilder();

          };//MazeBuilder是生成器

          class StandardMazeBuilder : public MazeBuilder {

          public:

              StandardMazeBuilder();

          /*

          */

              virtual void BuildMaze();

              virtual void BuildRoom(int);

              virtual void BuildDoor(int, int);

          /*

          */

              virtual Maze* GetMaze();

          private:

              Direction CommonWall(Room*, Room*);

              Maze* _currentMaze;

          };//StandardMazeBuilder是ConcreteBuilder,提供部件的具體構(gòu)造代碼

          Maze* MazeGame::CreateMaze (MazeBuilder& builder) {

              builder.BuildMaze();

              builder.BuildRoom(1);

              builder.BuildRoom(2);

              builder.BuildDoor(1, 2);

              return builder.GetMaze();

          }//CreateMaze是導(dǎo)向器,調(diào)用生成器的抽象接口完成產(chǎn)品的構(gòu)造過程。

          //下面代碼描述產(chǎn)品的構(gòu)造過程

          Maze* maze;//最終的產(chǎn)品

          MazeGame game;//Director,導(dǎo)航者

          StandardMazeBuilder builder;//ConcreteBuilder,實際的構(gòu)造類

          game.CreateMaze(builder);//開始裝配

          maze = builder.GetMaze();//獲取裝配后的產(chǎn)品

          posted @ 2010-03-31 21:07 常高偉 閱讀(240) | 評論 (0)編輯 收藏

          1.1 ABSTRACT FACTORY 抽象工廠

          1、 意圖

          提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定他們具體的類。

          2、 動機

          “客戶僅與抽象定義的接口交互,而不使用特定的具體類的接口。”

          這里的主要的思想是封裝對象的創(chuàng)建的過程。客戶端可以不需要知道具體要創(chuàng)建那些對象,而只需要知道創(chuàng)建某一系列的對象所用到的“工廠對象”即可。

          3、 適用性

          一個系統(tǒng)要獨立于它的產(chǎn)品的創(chuàng)建、組合和表示時。 

          一個系統(tǒng)要由多個產(chǎn)品系列中的一個來配置時。 

          當你要強調(diào)一系列相關(guān)的產(chǎn)品對象的設(shè)計以便進行聯(lián)合使用時。 

          當你提供一個產(chǎn)品類庫,而只想顯示它們的接口而不是實現(xiàn)時。 

          4、 結(jié)構(gòu)

          wps_clip_image-278

          5、 參與者

          AbstractFactory:創(chuàng)建一系列對象的抽象類。

          ConcreteFactory:實現(xiàn)具體創(chuàng)建產(chǎn)品對象的操作。

          AbstractProduct:為一類產(chǎn)品對象聲明一個接口。

          ConcreteProduct:定義一個被相應(yīng)的具體工廠創(chuàng)建的對象;實現(xiàn)AbstractProduct接口。

          Client:僅使用AbstractFactory和AbstractProduct類聲明的接口。

          6、 協(xié)作

          在運行時刻,創(chuàng)建一個ConcreteFactory實例,它創(chuàng)建具有特定實現(xiàn)的對象。為創(chuàng)建不同的對象,客戶應(yīng)使用不同的具體工廠。

          AbstractFactory將具體對象的創(chuàng)建延遲到它的子類ConcreteFactory中。

          7、 效果

          1) 它分離了具體的類:一個工廠封裝創(chuàng)建產(chǎn)品的責任和過程,它將客戶和類的實現(xiàn)分離。客戶通過抽象接口操作實例。產(chǎn)品的類名也在具體工廠實現(xiàn)中分離,他們不出現(xiàn)在客戶代碼中。

          2) 它使得易于交互產(chǎn)品系列。

          3) 它有利于產(chǎn)品的一致性。

          4) 難于支持新的種類。

          posted @ 2010-03-03 20:27 常高偉 閱讀(190) | 評論 (0)編輯 收藏

          1.1 設(shè)計模式怎樣解決設(shè)計問題

          1.1.1 尋找合適的對象

          面向?qū)ο笤O(shè)計最困難的部分是將系統(tǒng)分解為對象的集合。

          設(shè)計的許多對象來源于現(xiàn)實世界的分析模型,這里和領(lǐng)域驅(qū)動設(shè)計有點關(guān)聯(lián)。分析所得到的類,很多事現(xiàn)實中并不存在的類。這是抽象的結(jié)果。設(shè)計中的抽象對于產(chǎn)生靈活的設(shè)計至關(guān)重要。就像我設(shè)計的一個流程調(diào)度模型。

          1.1.2 決定對象的粒度

          記筆記可以讓我達到沉流的狀態(tài)。

          1.1.3 指定對象接口
          1.1.4 描述對象實現(xiàn)

          OMT表示法:

          1、 對象:最上面的黑體表示類名,下面依次是操作,數(shù)據(jù)。

          wps_clip_image-219

          2、 實例化:虛線箭頭表示一個類實例化另外一個對象。

          wps_clip_image-245

          3、 繼承:豎線和三角表示繼承關(guān)系。

          wps_clip_image-263

          4、 抽象類:類名以黑體斜體表示,操作也用斜體表示。

          5、 引用

          wps_clip_image-293

          箭頭加黑點表示一個類引用另外一個類。

          重點:

          1、 類的繼承和接口繼承的比較

          對象的類和對象的類型的區(qū)別:

          對象的類定義了對象是怎樣實現(xiàn)的,同時也定義了對象內(nèi)部狀態(tài)和操作的實現(xiàn)。對象的類型只與它的接口有關(guān)。一個對象可以由多個類型(支持多個接口),不同類的對象可以有相同的類型。

          類和類型緊密相連,類定義了對象的操作,也定義了對象的類型。

          類的繼承和接口的繼承的差別:

          c++中接口繼承接近于公有繼承純抽象類。純實現(xiàn)繼承或純類繼承接近于私有繼承。

          2、 對接口編程,而不是對實現(xiàn)編程——面向?qū)ο笤O(shè)計的第一個原則

          1.1.5 運用復(fù)用機制

          1、 繼承和組合的比較

          繼承是一種白箱復(fù)用,父類的內(nèi)部細節(jié)對子類可見。

          對象組合彼此不知道對方內(nèi)部細節(jié),成為黑箱復(fù)用。

          繼承的優(yōu)缺點:

          1) 子類可以直接重定義父類的操作。

          2) 編譯時刻決定了,無法在運行期間更改。

          3) 子類要知道父類的實現(xiàn)細節(jié),這樣就部分破壞了封裝性。子類和父類依賴過于緊密,父類的某些變化必然導(dǎo)致子類的變化。開發(fā)過程中遇到過類似的問題。這種依賴,限制了靈活性以及復(fù)用性。比如,服務(wù)體系中經(jīng)常出現(xiàn)這樣的問題,導(dǎo)致代碼拷貝。

          組合(通過獲得對象的引用而在運行時刻動態(tài)的定義)的優(yōu)缺點:

          1) 對象間通過接口彼此交互。

          2) 對象只能通過接口訪問,不要也不能知道對方細節(jié),這樣不會破壞封裝性。

          3) 運行時刻可以使用另外一個對象替換這個對象,提高了靈活性。

          4) 對象的實現(xiàn)基于接口編寫,所以實現(xiàn)上存在較少的依賴關(guān)系。

          5) 優(yōu)先使用組合有助于保持每個類被封裝,并被集中在單個任務(wù)上,提高整體內(nèi)聚性。類和類的層次都維持一個較小的規(guī)模,

          6) 基于對象組合的設(shè)計會有更多的對象(而又較少的類),且系統(tǒng)的行為依賴于對象間的關(guān)系而不是定義在某個類的內(nèi)部。

          理想的情況下,應(yīng)該通過組合原有構(gòu)件實現(xiàn)新的功能,而不是創(chuàng)建新的構(gòu)件。

          面向?qū)ο笤O(shè)計的第二個原則:優(yōu)先使用對象組合,而不是類繼承。

          2、 委托

          委托時一種組合方法,它是組合具有與繼承同樣的能力。

          委托的主要優(yōu)點在于它便于在運行時刻組合對象操作,以及更改操作的組合方式。它是軟件更加的靈活。

          和其他的技術(shù)方案相同,它也存在不足之處:增加了軟件的復(fù)雜度——動態(tài)的,高度參數(shù)化的軟件比靜態(tài)的軟件更難于理解。

          3、 繼承和參數(shù)化類型的比較

          1.1.6 關(guān)聯(lián)運行時刻的結(jié)構(gòu)和編譯時刻的結(jié)構(gòu)
          1.1.7 設(shè)計應(yīng)支持變化

          設(shè)計應(yīng)該支持變化——所說的是,一個設(shè)計方案,對變化要有一定的適應(yīng)性,即封裝變化。

          變化是導(dǎo)致重新設(shè)計的原因。設(shè)計要對一定范圍內(nèi)的變化友好。

          4、 

          對于程序的分層設(shè)計,對于處于同一分層的模塊,對外應(yīng)保持一定的抽象,并且,使用同種類型的通信協(xié)議。

          posted @ 2010-03-03 20:26 常高偉 閱讀(435) | 評論 (0)編輯 收藏

          1.1 變量存儲域

          1.1.1 一個示例

          pang123hui首先提供了一個網(wǎng)上流傳的學(xué)習(xí)代碼示例:

          int a = 0; //全局區(qū) 

          void main() 

          {

          int b; //棧 

          char s[] = “abc”; //s在棧,abc在文字常量區(qū) 

          char *p1,*p2; //棧 

          char *p3 = "123456"; //123456在常量區(qū),p3在棧上 

          static int c =0; //全局區(qū) 

          p1 = (char *)malloc(10); //p1在棧,分配的10字節(jié)在堆 

          p2 = (char *)malloc(20); //p2在棧,分配的20字節(jié)在堆 

          strcpy(p1, "123456"); //123456放在常量區(qū) 

          }

          這個代碼示例中出現(xiàn)了“全局區(qū)”,“棧”,“文字常量區(qū)”,“堆”等詞語。為了統(tǒng)一,我們使用《C專家編程》中的說法:堆棧段,BSS段,數(shù)據(jù)段,文本段。

          各個段的作用如下:

          1、 文本段:包含程序的指令,它在程序的執(zhí)行過程中一般不會改變。

          2、 數(shù)據(jù)段:包含了經(jīng)過初始化的全局變量和靜態(tài)變量,以及他們的值。

          3、 BSS段:包含未經(jīng)初始化的全局變量和靜態(tài)變量。

          4、 堆棧段:包含了函數(shù)內(nèi)部聲明的局部變量。

          當然,上面段的作用不僅于此,具體的作用會在下面的知識點中介紹。

          1.1.2 通過代碼測試變量的存儲位置

          Linux下可以通過系統(tǒng)命令“size”查看可以執(zhí)行程序各個段的大小。但是,可執(zhí)行程序中的段結(jié)構(gòu)和運行中程序在內(nèi)存中的段結(jié)構(gòu)并不完全相同,但是有一定的映射關(guān)系。具體如下圖所示(圖片信息來自《C專家編程》):

          wps_clip_image-696

          下面通過代碼示例和“size”來研究變量的存儲區(qū)域。

          test.c

          int main()

          {

          return 1;

          }

          編譯,并且查看可執(zhí)行程序各個段的大小:

          wps_clip_image-779

          更改test.c:

          int g_data;

          int main()

          {

          return 1;

          }

          編譯,并且查看可執(zhí)行程序各個段的大小:

          wps_clip_image-849

          可以發(fā)現(xiàn),文本段,數(shù)據(jù)段都沒有發(fā)送變化,而BSS段增加了4個字節(jié)。

          結(jié)論1:未初始化的全局變量保存在BSS段中

          繼續(xù):

          int g_data = 1;

          int main()

          {

          return 1;

          }

          編譯:

          wps_clip_image-958

          可以發(fā)現(xiàn),BSS段和文本段相同,而數(shù)據(jù)段增加了4個字節(jié)。

          結(jié)論2:經(jīng)過初始化的全局變量保存在數(shù)據(jù)段中

          繼續(xù):

          int main()

          {

          static int g_data;

          return 1;

          }

          編譯:

          wps_clip_image-1066

          可以發(fā)現(xiàn),文本段,數(shù)據(jù)段都沒有發(fā)送變化,而BSS段增加了4個字節(jié)。

          結(jié)論3:未初始化的靜態(tài)變量保存在BSS段中

          繼續(xù):

          int main()

          {

          static int g_data = 1;

          return 1;

          }

          編譯:

          wps_clip_image-1183

          可以發(fā)現(xiàn),BSS段和文本段相同,而數(shù)據(jù)段增加了4個字節(jié)。

          結(jié)論4:經(jīng)過初始化的靜態(tài)變量保存在數(shù)據(jù)段中

          繼續(xù):

          int main()

          {

          int i_data = 1;

          return 1;

          }

          編譯:

          wps_clip_image-1288

          可以發(fā)現(xiàn),BSS段和和數(shù)據(jù)段相同,而文本段增加了16個字節(jié)。局部變量會在執(zhí)行的時候在堆棧段中生成,函數(shù)執(zhí)行完畢后釋放。

          結(jié)論5:函數(shù)內(nèi)部聲明的局部變量保存在堆棧段中

          繼續(xù):

          const int g_data = 1;

          int main()

          {

          return 1;

          }

          編譯:

          wps_clip_image-1430

          把全局變量定義為“const”后,也許你會感到奇怪,怎么BSS段和數(shù)據(jù)段都沒有發(fā)生變化,而文本段卻增加了4個字節(jié)。

          結(jié)論6:const修飾的全局變量保存在文本段中

          那么,const的局部變量?

          繼續(xù):

          int main()

          {

          const int i_data = 1;

          return 1;

          }

          編譯:

          wps_clip_image-1587

          結(jié)論7:const修飾的局部變量保存在堆棧段中

          繼續(xù):

          char *pstr = "";

          int main()

          {

          return 1;

          }

          編譯:

          wps_clip_image-1666

          在做一下更改:

          char *pstr = "123456789";

          int main()

          {

          return 1;

          }

          編譯:

          wps_clip_image-1733

          可以發(fā)現(xiàn),前后數(shù)據(jù)段和BSS段大小均未發(fā)生變化,而文本段增加了9個字節(jié)。

          結(jié)論8:字符串常量保存在文本段中

          1.1.3 結(jié)論

          1、 經(jīng)過初始化的全局變量和靜態(tài)變量保存在數(shù)據(jù)段中。

          2、 未經(jīng)初始化的全局變量和靜態(tài)變量保存在BSS段。

          3、 函數(shù)內(nèi)部聲明的局部變量保存在堆棧段中。

          4、 const修飾的全局變量保存在文本段中,const修飾的局部變量保存在堆棧段中。

          5、 字符串常量保存在文本段中。

          1.1.4 擴展閱讀

          《C專家編程》第6章——詳細介紹各個段的作用。

          posted @ 2010-03-03 02:38 常高偉 閱讀(295) | 評論 (0)編輯 收藏

          讀S計劃的理念

          自助、互助,共同進步!

           

          讀S計劃的初衷

          現(xiàn)在有很多學(xué)習(xí)方式,搜索引擎、論壇、博客,qq群等等,那么我這樣的計劃還有存在的必要么?這個計劃的獨特之處在哪里?

          讀S計劃的獨特之處不在于其學(xué)習(xí)內(nèi)容和方式,學(xué)習(xí)的內(nèi)容我們可以根據(jù)實際情況調(diào)整,可以由多個人同時引導(dǎo)多個學(xué)習(xí)方向,這些都不是程式化的,也不是重點。

          讀S計劃的獨特之處在于其理念:致力于形成一種有計劃、有組織,強調(diào)互動、互助和共同進步的學(xué)習(xí)模式和氛圍。讀S計劃不是一個單純的興趣小組,我們會按照計劃不斷的切換話題。讀S計劃也不是提問的好地方,在每個階段,我們都有限定的討論范圍,所以無關(guān)的問題很容易被忽略。讀S計劃希望多數(shù)人以積極的心態(tài)參與進來,更多的討論、研究和貢獻您的想法,而不是被動的接受和看,我們不希望將學(xué)習(xí)計劃做成課堂模式,我們希望做成項目的模式 。讀S計劃致力于將信息以信息本身進行聚合,而不是以人進行聚合,因為學(xué)習(xí)計劃在不斷推進,所以不存在永遠的權(quán)威人士,但知識本身是客觀、中立的、權(quán)威的。

           

          共建新型技術(shù)社區(qū)

          建立新型的、關(guān)系緊密的、以知識體系為軸、強調(diào)經(jīng)驗積累與分享的的技術(shù)社區(qū)。

           

          更深入了解此計劃,可以閱讀:

          《技術(shù)族譜 之 讀S計劃:讓我們一起快樂學(xué)習(xí)》

          《準備啟動一個開源項目 - 技術(shù)族譜 - 先期利用Goolge云計算平臺》

          《關(guān)于“讀S計劃”的聊天記錄:統(tǒng)一理念,確定目前的工作》

          《授人以“魚”,不如授人以“漁”,放棄一個目標,設(shè)定另一個目標》

          期待你加入我們的群組:http://hi.csdn.net/space-mtag-tagid-37.html

          posted @ 2009-10-14 21:43 常高偉 閱讀(206) | 評論 (0)編輯 收藏


          posts - 19, comments - 0, trackbacks - 0, articles - 0

          Copyright © 常高偉

          主站蜘蛛池模板: 柳河县| 汶上县| 宜春市| 陆丰市| 赤峰市| 焦作市| 定南县| 沙田区| 镇坪县| 青神县| 古浪县| 广宁县| 岳西县| 福贡县| 三亚市| 凌源市| 遂宁市| 镇宁| 聊城市| 柏乡县| 台州市| 岳池县| 手游| 吉林市| 长垣县| 醴陵市| 上蔡县| 梁平县| 简阳市| 夹江县| 皮山县| 三江| 衡水市| 宁国市| 横峰县| 新昌县| 长阳| 丰都县| 扎赉特旗| 承德县| 江北区|