C++設(shè)計(jì)模式第三講_第1頁(yè)
C++設(shè)計(jì)模式第三講_第2頁(yè)
C++設(shè)計(jì)模式第三講_第3頁(yè)
C++設(shè)計(jì)模式第三講_第4頁(yè)
C++設(shè)計(jì)模式第三講_第5頁(yè)
已閱讀5頁(yè),還剩39頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、C+設(shè)計(jì)模式教程第三講:Builder和Prototype模式主講人:步磊峰 UIPower 3D界面引擎負(fù)責(zé)人第一節(jié): Builder模式定義2定義: 將一個(gè)復(fù)雜對(duì)象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 這樣的設(shè)計(jì)模式被稱為建造者模式。 那么如何理解這句話的含義呢? 我們?nèi)耘f使用汽車制造的例子來進(jìn)行相關(guān)的演示。 第二節(jié): Builder模式例子3 1、汽車的是一個(gè)復(fù)雜的產(chǎn)品,一個(gè)汽車公司組裝一輛汽車,需要一定的步驟,例如需要組裝引擎,底盤以及輪子 等。 2、專業(yè)的事情由專業(yè)的公司,例如引擎可以由專業(yè)的生產(chǎn)商,例如勞斯萊斯,通用汽車等生產(chǎn)。 同樣的輪胎可以由普利司通或米其

2、林等專業(yè)公司進(jìn)行生產(chǎn)。汽車廠商很多時(shí)候是將專業(yè)公司生產(chǎn)的部件組合起 來,從而組裝成成車。 這意味著不同的汽車生產(chǎn)商使用相同的部件。 那么我們來定義Car的數(shù)據(jù)結(jié)構(gòu),代表著一個(gè)復(fù)雜的產(chǎn)品。 第二節(jié): Builder模式例子4 第二節(jié): Builder模式例子5 第二節(jié): Builder模式例子6 3、將一個(gè)復(fù)雜對(duì)象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 前面定義了一個(gè)復(fù)雜對(duì)象Car。根據(jù)定義,Car的構(gòu)造與它的表示分離。意味著,Car我們僅僅定義了它的表示, 是由生產(chǎn)廠商信息以及引擎,底盤和輪子組成,但是如何構(gòu)造它并不是在Car的構(gòu)造器中進(jìn)行構(gòu)造,而是使用引 進(jìn)一個(gè)構(gòu)造器來來

3、進(jìn)行復(fù)雜對(duì)象Car的構(gòu)造。 根據(jù)定義,使用同樣的構(gòu)造過程可以創(chuàng)建不同的表示。 這句話的意思意味著構(gòu)造器構(gòu)造復(fù)雜對(duì)象Car是具有一定的流程的,而且在Builder的過程中,可以創(chuàng)建出不同汽 車廠商生產(chǎn)的汽車,同一生產(chǎn)商的汽車使用各個(gè)專業(yè)公司生產(chǎn)的引擎或輪胎等等?;蛘卟煌钠嚿a(chǎn)廠商生產(chǎn) 出來的汽車使用同一專業(yè)公司的引擎或輪胎等等。 這些都意味著創(chuàng)建不同的表示(Car的不同表示)。 第二節(jié): Builder模式例子7 4、由此可見,Builder模式的核心是: 復(fù)雜產(chǎn)品的表示與創(chuàng)建分離。 強(qiáng)調(diào)創(chuàng)建的過程或流程是有步驟的,甚至可以強(qiáng)制要求有先后順序。 產(chǎn)品的不同表現(xiàn)形式不是通過產(chǎn)品繼承擴(kuò)展而來的,

4、而是通過繼承擴(kuò)展創(chuàng)建器而來的。 第二節(jié): Builder模式例子8 第二節(jié): Builder模式例子9通過Builder創(chuàng)建產(chǎn)品通過繼承Builder創(chuàng)建產(chǎn)品的不同表示:此處創(chuàng)建的是通用汽車的產(chǎn)品 第二節(jié): Builder模式例子10通過Builder創(chuàng)建產(chǎn)品通過繼承Builder創(chuàng)建產(chǎn)品的不同表示:此處創(chuàng)建的是福特汽車的產(chǎn)品 第二節(jié): Builder模式例子11我們?cè)俣x指導(dǎo)類用于簡(jiǎn)化創(chuàng)建過程 定義測(cè)試函數(shù) 第二節(jié): Builder模式一個(gè)簡(jiǎn)單例子12第三節(jié): 創(chuàng)建者模式和工廠模式的區(qū)別13 Factory模式中: 1、有一個(gè)抽象的工廠。 2、實(shí)現(xiàn)一個(gè)具體的工廠-汽車工廠。 3、工廠生產(chǎn)汽車

5、A,得到汽車產(chǎn)品A。 4、工廠生產(chǎn)汽車B,得到汽車產(chǎn)品B。 這樣做,實(shí)現(xiàn)了購(gòu)買者和生產(chǎn)線的隔離。強(qiáng)調(diào)的是結(jié)果。 Builder模式: 1、引擎工廠生產(chǎn)引擎產(chǎn)品,得到汽車部件A。 2、輪胎工廠生產(chǎn)輪子產(chǎn)品,得到汽車部件B。 3、底盤工廠生產(chǎn)車身產(chǎn)品,得到汽車部件C。 4、將這些部件放到一起,形成剛好能夠組裝成一輛汽車的整體。 5、將這個(gè)整體送到汽車組裝工廠,得到一個(gè)汽車產(chǎn)品。 這樣做,目的是為了實(shí)現(xiàn)復(fù)雜對(duì)象生產(chǎn)線和其部件的解耦。強(qiáng)調(diào)的是過程。 第三節(jié): 創(chuàng)建者模式和工廠模式的區(qū)別14 兩者的區(qū)別在于: Factory模式不考慮對(duì)象的組裝過程,而直接生成一個(gè)我想要的對(duì)象。 Builder模式先一個(gè)

6、個(gè)的創(chuàng)建對(duì)象的每一個(gè)部件,再統(tǒng)一組裝成一個(gè)對(duì)象。 Factory模式所解決的問題是,工廠生產(chǎn)產(chǎn)品。 而Builder模式所解決的問題是工廠控制產(chǎn)品生成器組裝各個(gè)部件的過程,然后從產(chǎn)品生成器中得到產(chǎn)品。 Builder模式不是很常用。模式本身就是一種思想。知道了就可以了。 設(shè)計(jì)模式就是一種思想。學(xué)習(xí)一個(gè)模式,花上一兩個(gè)小時(shí)把此模式的意思理解了,就 夠了。其精華的所在會(huì)在以后工作的設(shè)計(jì)中逐漸體現(xiàn)出來。 第四節(jié): 創(chuàng)建者模式描述15 1、意圖: 將一個(gè)復(fù)雜對(duì)象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 2、結(jié)構(gòu): 第四節(jié): 創(chuàng)建者模式描述16 3、參與者: 1) Builder:為創(chuàng)

7、建一個(gè)產(chǎn)品對(duì)象的各個(gè)部件指定抽象接口。 2) ConcreteBuilder:實(shí)現(xiàn)Builder的接口以構(gòu)造和裝配該產(chǎn)品的各個(gè)部件,定義并明確它所創(chuàng)建的表示,并 提供一個(gè)檢索產(chǎn)品的接口。 3) Director:構(gòu)造一個(gè)使用Builder接口的對(duì)象。 4) Product:表示被構(gòu)造的復(fù)雜對(duì)象。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程,包含定 義組成部件的類,包括將這些部件裝配成最終產(chǎn)品的接口。 4、 適用: 1) 當(dāng)創(chuàng)建復(fù)雜對(duì)象的算法應(yīng)該獨(dú)立于該對(duì)象的組成部分以及它們的裝配方式時(shí)。 2) 當(dāng)構(gòu)造過程必須允許被構(gòu)造的對(duì)象有不同表示時(shí)。 第五節(jié): 原型模式定義17定義

8、: 用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝原型創(chuàng)建新的對(duì)象。 1) Prototype原型模式是一種創(chuàng)建型設(shè)計(jì)模式,Prototype模式允許一個(gè)對(duì)象再創(chuàng)建另外一個(gè)可定制的對(duì)象,根本 無需知道任何如何創(chuàng)建的細(xì)節(jié)。 2) 工作原理是: 通過將一個(gè)原型對(duì)象傳給那個(gè)要發(fā)動(dòng)創(chuàng)建的對(duì)象,這個(gè)要發(fā)動(dòng)創(chuàng)建的對(duì)象通過請(qǐng)求原型對(duì)象拷貝它 們自己來實(shí)施創(chuàng)建。 3) 原型模式主要面對(duì)的問題是:“某些結(jié)構(gòu)復(fù)雜的對(duì)象”的創(chuàng)建工作;由于需求的變化,這些對(duì)象經(jīng)常面臨著劇 烈的變化,但是他們卻擁有比較穩(wěn)定一致的接口。 第六節(jié): 原型模式例子18 我們使用簡(jiǎn)歷復(fù)制的例子來演示原型設(shè)計(jì)模式: ICloneable代表一個(gè)pr

9、ototype:定義工作經(jīng)歷類:第六節(jié): 原型模式例子19 定義工作經(jīng)歷類:第六節(jié): 原型模式例子20 定義簡(jiǎn)歷類,繼承自ICloneable原型接口:第六節(jié): 原型模式例子21 定義簡(jiǎn)歷類,繼承自ICloneable原型接口:第六節(jié): 原型模式例子22 測(cè)試程序:第七節(jié): 原型模式中淺拷貝和深拷貝23 前面的例子貌似沒什么大問題。 這是因?yàn)椋?1) 所有的數(shù)據(jù)類型都是string或int ,例如Resume類的個(gè)人信息部分,除了年齡使用int類型外,其他的信息都 是使用string。string類內(nèi)部的賦值使用逐字符拷貝,因此是深拷貝。而基本數(shù)據(jù)類型賦值都是獨(dú)立的實(shí)例。不存 在淺拷貝的問題。

10、 2) 同樣的,WorkExperience類的公司和工作年限也是使用字符串。 3) Resume的成員變量m_workExperience使用的是對(duì)象,意味著每個(gè)Resume都有一個(gè)獨(dú)立的WorkExperience對(duì) 象。而沒有使用共享的指針形式。 如果我們修改Resume類,不使用對(duì)象,而是使用指針方式,并且不是使用組合而是使用聚合的形式,那么我們會(huì) 發(fā)現(xiàn)存在很大的問題。 第七節(jié): 原型模式中淺拷貝和深拷貝24 第七節(jié): 原型模式中淺拷貝和深拷貝25 第七節(jié): 原型模式中淺拷貝和深拷貝26 第八節(jié): 實(shí)現(xiàn)原型模式中深拷貝27 前面的實(shí)例代碼中Resum2用于一個(gè)WortExperienc

11、e指針,而WorkExperience并不是繼承自ICloneable接口,現(xiàn)在我要實(shí)現(xiàn)深度拷貝,則定義一個(gè)WorkExperience2類,讓其繼承自IConeable接口,并實(shí)現(xiàn)深度拷貝的Clone方法第八節(jié): 實(shí)現(xiàn)原型模式中深拷貝28然后修改Resume2類中的m_workExperience指針的類型為WorkExperience2。最后我們修改Resume2的拷貝構(gòu)造函數(shù):不需要修改Resume2的Clone方法:第八節(jié): 實(shí)現(xiàn)原型模式中深拷貝29測(cè)試代碼不用更改,我們運(yùn)行看一下結(jié)果:第九節(jié): 防止深度拷貝后的內(nèi)存泄露30對(duì)于前面所述的內(nèi)存泄露,最簡(jiǎn)單的方式是:在Resume2中添加

12、一個(gè)方法:然后在需要內(nèi)存釋放的時(shí)候手動(dòng)的進(jìn)行delete:第九節(jié): 防止深度拷貝后的內(nèi)存泄露31然后在需要內(nèi)存釋放的時(shí)候手動(dòng)的進(jìn)行delete:第九節(jié): 防止深度拷貝后的內(nèi)存泄露32我們需要實(shí)現(xiàn)一種機(jī)制,不管是深度Clone或淺Clone,都要能夠防止內(nèi)存泄露并且具有智能性,最起碼當(dāng)我們調(diào)用delete Resume2的時(shí)候,能夠自動(dòng)的將Clone出來的WorkExperience指針也能夠得到釋放。可能第一個(gè)反應(yīng)就是修改ICloneable接口,用標(biāo)記變量標(biāo)記出是否是深度Clone例如:第九節(jié): 防止深度拷貝后的內(nèi)存泄露33讓W(xué)orkExperience3和Resume3都繼承自IClone

13、able3接口,由于重復(fù)代碼比較多,我們僅演示核心部分:第九節(jié): 防止深度拷貝后的內(nèi)存泄露34對(duì)WorkExperience3和Resume3進(jìn)行測(cè)試第九節(jié): 防止深度拷貝后的內(nèi)存泄露35第九節(jié): 防止深度拷貝后的內(nèi)存泄露36第九節(jié): 防止深度拷貝后的內(nèi)存泄露37前面的代碼實(shí)際遇到了指針兩次釋放的問題,要明確指針本身的值和指向的值是不同的概念,指針NULL判斷是根據(jù)自己的值進(jìn)行判斷,而不是判斷指向的值是否為NULL。下面一段代碼演示了指針的用法:由此可見,我們使用標(biāo)記方式無法妥善的解由此可見,我們使用標(biāo)記方式無法妥善的解決深度拷貝后的內(nèi)存泄露問題。決深度拷貝后的內(nèi)存泄露問題??磥碇荒苁褂弥悄苤?/p>

14、針來解決內(nèi)存泄露的問看來只能使用智能指針來解決內(nèi)存泄露的問題。題。第十節(jié): 使用智能指針防止內(nèi)存泄露381、我們直接使用前面已經(jīng)實(shí)現(xiàn)的WorkExperience2類,其繼承自ICloneable,實(shí)現(xiàn)了深度Clone方法2、實(shí)現(xiàn)ResumePtr類,也繼承自ICloneable第十節(jié): 使用智能指針防止內(nèi)存泄露393、其他的方法和Resume3相同代碼,我們不再貼出來4、測(cè)試結(jié)果第十節(jié): 使用智能指針防止內(nèi)存泄露405、測(cè)試結(jié)果第十節(jié): 使用智能指針防止內(nèi)存泄露41結(jié)論:由此可見使用原型克隆模式面臨兩個(gè)主要的問題:1、如何正確的實(shí)現(xiàn)Clone方法,當(dāng)對(duì)象結(jié)構(gòu)包含循環(huán)引用時(shí),尤為棘手。 還需要

15、考慮Clone是深度克隆還是淺Clone,這依賴于程序的需求。 2、如何對(duì)克隆后的對(duì)象的析構(gòu)。上述內(nèi)容其實(shí)都涉及到語(yǔ)言機(jī)制問題。上述兩個(gè)問題在C#或Java中很容易解決,對(duì)于深度克隆或循環(huán)引用,可以使用對(duì)象序列化機(jī)制將整個(gè)對(duì)象以及所有依賴的對(duì)象遞歸的進(jìn)行序列化到內(nèi)存流中,然后從內(nèi)存流反序列化到一個(gè)新的對(duì)象中,這樣就完成了深度克隆。當(dāng)然在C+中我們可以使用boost的序列化框架獲得同樣的效果。關(guān)于內(nèi)存析構(gòu)問題。C#或Java具有引用計(jì)數(shù)和垃圾收集功能。而C+中我們可以使用shared_ptr智能指針模擬簡(jiǎn)單的垃圾收集功能。第十一節(jié): 原型模式描述42 1、意圖: 用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。 2、結(jié)構(gòu): 第十一節(jié): 原型模式描述43 3、參與者: 1) Prototy

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論