1. 程式人生 > >cocos2d-x設計模式發掘之二:二段構建模式

cocos2d-x設計模式發掘之二:二段構建模式

乍一看標題,大家可能會覺得很奇怪,神馬是“二段構建模式”呢?

所謂二段構建,就是指建立物件時不是直接通過構建函式來分配記憶體並完成初始化操作。取而代之的是,建構函式只負責分配記憶體,而初始化的工作則由一些名為initXXX的成員方法來完成。然後再定義一些靜態類方法把這兩個階段組合起來,完成最終物件的構建。因為在《Cocoa設計模式》一書中,把此慣用法稱之為“Two Stage Creation”,即“二段構建”。因為此模式在cocos2d裡面被廣泛使用,所以把該模式也引入過來了。

1.應用場景:

二段構建在cocos2d-x裡面隨處可見,自從2.0版本以後,所有的二段構建方法的簽名都改成create了。這樣做的好處是一方面統一介面,方便記憶,另一方面是以前的類似Cocoa的命名規範不適用c++,容易引起歧義。下面以CCSprite為類,來具體闡述二段構建的過程,請看下列程式碼:
//此方法現在已經不推薦使用了,將來可能會刪除

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CCSprite* CCSprite::spriteWithFile(const char *pszFileName) { return CCSprite::create(pszFileName); } CCSprite* CCSprite::create(const char *pszFileName) { CCSprite *pobSprite = new CCSprite(); //1.第一階段,分配記憶體 if (pobSprite && pobSprite->initWithFile(pszFileName))
//2.第二階段,初始化 { pobSprite->autorelease(); //!!!額外做了記憶體管理的工作。 return pobSprite; } CC_SAFE_DELETE(pobSprite); return NULL; }

如上面程式碼中的註釋所示,建立一個sprite明顯被分為兩個步驟:1.使用new來建立記憶體;2.使用initXXX方法來完成初始化。
因為CCSprite的建構函式也有初始化的功能,所以,我們再來看看CCSprite的構建函式實現:

?
1 CCSprite::CCSprite(void): m_pobTexture(NULL), m_bShouldBeHidden(
false){}

很明顯,這個構建函式所做的初始化工作非常有限,僅僅是在初始化列表裡面初始化了m_pobTexture和m_bShouldBeHidden兩個變數。實際的初始化工作大部分都放在initXXX系列方法中,大家可以動手去檢視原始碼。

2.分析為什麼要使用此模式?

這種二段構建對於C++程式設計師來說,其實有點彆扭。因為c++的建構函式在設計之初就是用來分配記憶體+初始化物件的。如果再搞個二段構建,實則是多此一舉。但是,在objective-c裡面是沒有建構函式這一說的,所以,在Cocoa的程式設計世界裡,二段構建被廣泛採用。而cocos2d-x當初是從cocos2d-iphone移植過來了,為了保持最大限度的程式碼一致性,所以保留了這種二段構建方式。這樣可以方便移植cocos2d-iphone的遊戲,同時也方便cocos2d-iphone的程式設計師快速上手cocos2d-x。

不過在後來,由於c++天生不具備oc那種可以指定每一個引數的名稱的能力,所以,cocos2d-x的設計者決定使用c++的函式過載來解決這個問題。這也是後來為什麼2.0版本以後,都使用create函式的過載版本了。

雖然介面簽名改掉了,但是本質並沒有變化,還是使用的二段構建。二段構建並沒有什麼不好,只是更加突出了物件需要初始化。在某種程度上也可以說是一種設計強化。因為忘記初始化是一切莫名其妙的bug的罪魁禍首。同時,二段構建出來的物件都是autorelease的物件,而autorelease物件是使用引用計數來管理記憶體的。客戶端程式設計師在使用此介面建立物件的時候,無需關心具體實現細節,只要知道使用create方法可以建立並初始化一個自動釋放記憶體的物件即可。

在一點,在《Effective Java》一書中,也有提到。為每一個類提供一個靜態工廠方法來代替建構函式,它有以下三個優點:
1.與建構函式不同,靜態方法有名字,而建構函式只能通過引數過載。
2.它每次被呼叫的時候,不一定都建立一個新的物件。比如Boolean.valueOf(boolean)。
3.它還可以返回原型別的子型別物件。

因此,使用二段構建的原因有二:
1.相容性、歷史遺留原因。(這也再次印證了一句話,一切系統都是遺留系統,呵呵)
2.二段構建有其自身獨有的優勢。

3.使用此模式的優缺點是什麼?
優點:
1.顯示分開記憶體分配和初始化階段,讓初始化地位突出。因為程式設計師一般不會忘記分配記憶體,但卻常常忽略初始化的作用。
2.見上面分析《Effective Java》的第1條:“為每一個類提供一個靜態工廠方法來代替建構函式”
3.除了完成物件構建,還可以管理物件記憶體。
缺點:
1.不如直接使用建構函式來得直白、明瞭,違反直覺,但這個是相對的。

4.此模式的定義及一般實現
定義:
將一個物件的構建分為兩個步驟來進行:1.分配記憶體 2.初始化
它的一般實現如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Test { public: //靜態工廠方法 static Test* create() { Test *pTest = new Test; if (pTest && pTest->init()) { //這裡還可以做其它操作,比如cocos2d-x裡面管理記憶體 return pTest; } return NULL; } // Test() { //分配成員變數的記憶體,但不初始化 } bool init(){ //這裡初始化物件成員 return true; }

相關推薦

cocos2d-x設計模式發掘構建模式

乍一看標題,大家可能會覺得很奇怪,神馬是“二段構建模式”呢? 所謂二段構建,就是指建立物件時不是直接通過構建函式來分配記憶體並完成初始化操作。取而代之的是,建構函式只負責分配記憶體,而初始化的工作則由一些名為initXXX的成員方法來完成。然後再定義一些靜態類方法

Cocos2d-x設計模式觀察者模式

1、應用場景 前面在介紹單例模式的時候,提到了一個類CCNotificationCenter,它除了應用單例模式以外,還應用了觀察者模式。CCNotificationCenter類是觀察者模式中的目標物件,而CCNotificationObserver則是觀察者。 一個目標物件可以註冊多個觀察者,當目標物件

Cocos2d-x設計模式發掘之一單例模式

本系列文章我將和大家一起來發掘cocos2d-x中所使用到的設計模式,同樣的,這些模式在cocos2d-iphone中也可以找到其身影。 宣告:這裡發掘模式只是我的個人愛好,通過這個過程,我希望能加深自己對於設計模式運用的理解。關於模式的學習,市面上已經有許多非常好的書

設計模式系列抽象工廠模式

前言 在設計模式有三個模式是與工廠模式相關的,分別是:簡單工廠模式、工廠方法模式以及抽象工廠模式。在前面的文章中已經談到前面兩種,這裡就對抽象工廠模式介紹一下。抽象工廠模式就是提供一個建立一系列相關或者相互依賴的介面(也就是抽象類),而無需指定具體的類。簡單來

設計模式迭代器模式

1. 前言        迭代器模式(Iterator)提供了一種方法,它可以順序訪問一個物件當中的各個元素,但是又不暴露這個聚合物件的內部標示。聽起來和遍歷很像,個人感覺就是遍歷,即是,迭代器提供了一個方法,可以順序物件內部的某個容器,而不用知道容器中存放的是什麼型別.在

設計模式迭代器模式(Iterator Pattern)

GOF 在《設計模式》:提供一種方法順序訪問一個聚合物件中的各個元素,而又不暴露該物件的內部表示。 迭代器模式 是物件行為模式。 聚合:是指一組物件的組合結構,比如:java 中的集合,陣列等。思想:迭代模式的關鍵思想就是把聚合物件的遍歷個訪問從聚合物件中分離出來,放入單

設計模式介紹命令模式(command)

    命令(模式)的結構很簡單,但對於消除程式碼間的耦合卻有著重要的影響。     在 C 語言中我們經常使用回撥函式,而命令模式是回撥( callback )的面向物件的替代物。從最直觀的角度來看,命令模式就是一個函式物件:一個作為物件的函式。通過將函式封裝為物件,就能

設計模式系列建造者模式

1.定義 將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示 2.通用類圖 Product 產品類:表示被構造的複雜物件。通常實現了模板方法模式,也就是有基本方法和模板方法 Builder 抽象建造者:規範產品的元件,一

設計模式系列工廠模式(Factory Pattern)

這是本系列的第三篇部落格,這次主要來說一下工廠模式。 基本工廠模式 簡單來說工廠模式是將工程中的相同型別物件的建立活動集中管理,一般通過反射來生成外界需要的實體類。比如Spring中的容器Bean概念,通過Spring BeanFactory來產生不同的Be

23種設計模式(13)叠代器模式

關系 想象 遍歷集合 spa 意思 比較 使用 string 對象方法 定義:提供一種方法訪問一個容器對象中各個元素,而又不暴露該對象的內部細節。 類型:行為類模式。 類圖: 如果要問java中使用最多的一種模式,答案不是單例模式,也不是工廠模式,更不是策略模式,而是

《淺談架構前後端分離模式

前言:分離模式   對前後端分離研究了一段時間,恰逢公司有一個大專案決定嘗試使用前後端分離模式進行,便參與其中。該專案從2016年初立項至今,平平穩穩得度過,但也湧現出越來越多的問題,絕對不是說前後端分離模式不好,而是很多公司在嘗試前後端分離的時候沒有做好充分得

【AMQ】 點對點模式Dome

AMQ通訊分為兩種,一種是點對點模式,另一種是釋出訂閱模式,本文主要介紹點對點模式和簡單實現。 什麼是點對點模式? 點對點模式是AMQ的一種通過佇列方式通訊的模式, 即生產者會把生產的訊息放在某個佇列中,消費者從佇列中取得訊息進行通訊的方式。 基本實現: 生產者

java 設計模式01簡單工廠和抽象工廠模式

總結一下: 簡單工廠:工廠根據條件去建立對應的具體實現物件,如果需要增加新的物件,就必須修改建立物件的介面,增加判斷條件,另外可能建立的物件下面的方法也可能有其他物件去實現相同的功能,造成混亂,比如,amd可以造cpu,也可以造網絡卡,不能建立了一個amd造cpu的

【java設計模式 單例(Singleton)模式

1. 單例模式的定義         單例模式(Singleton Pattern)是一個比較簡單的模式,其原始定義如下:Ensure a class has only one instance, and provide a global point of access

maven構建docker映象三部曲編碼和構建映象

在《maven構建docker映象三部曲之一:準備環境》中,我們在vmware上準備好了ubuntu16虛擬機器,並且裝好了docker、jdk8、maven等必備工具,現在我們來開發一個java web工程,再用docker-maven-plugin外掛來

JAVA設計模式(15)迭代器模式

迭代器模式是Java和.Net程式設計環境中非常常用的設計模式。此模式用於以順序方式訪問集合物件的元素,而不需要知道其底層表示。迭代器模式屬於行為模式類別。 實現例項 在這個例項中,將建立一個Iterator介面,它陳述了一個導航方法和一個Container介面,以及返回迭代器。 實現Con

Spark程式設計指南Spark分散式叢集模式的執行時系統架構

文章目錄 官方叢集模式介紹 Cluster Manager有哪些? Standalone Apache Mesos Hadoop YARN Kubernetes Standalone模

Web開發前後端開發模式探討

在去年一年的開發過程中,基於開發中MVC的分層模式,我們在實際的專案中嘗試了前後端分離的開發模式,並在幾個專案中都堅持了下來,雖然堅持了,但不能說明實際的效果很好,或者解決了我們專案開發中存在的問題。就像做軟體維護一樣,經常會解決一個Bug,又引入多個Bug,在新的開發模式

九度筆記 1467叉排序樹

題目1467:二叉排序樹 時間限制:1 秒 記憶體限制:128 兆 特殊判題:否 提交:1292 解決:518 題目描述:         二叉排序樹,也稱為二叉查詢樹。可以是一顆空樹,也可以是一顆具有如下特性的非空二叉樹:         1

JAVA設計模式(16)行為型-策略模式(Strategy)

俗話說:條條大路通羅馬。在很多情況下,實現某個目標的途徑不止一條,例如我們在外出旅遊時可以選擇多種不同的出行方式,如騎自行車、坐汽車、坐火車或者坐飛機,可根據實際情況(目的地、旅遊預算、旅遊時間等)來選擇一種最適合的出行方式。在制訂旅行計劃時,如果目的地較遠、時間不多,但