程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 由Cocos2d-x工程入口窺見代理模式,cocos2d-x窺見

由Cocos2d-x工程入口窺見代理模式,cocos2d-x窺見

編輯:C++入門知識

由Cocos2d-x工程入口窺見代理模式,cocos2d-x窺見


  關於設計模式(Design Pattern),自從“四人幫”第一次在《Design Patterns: Elements of Reusable Object-Oriented Software》中將其上升到理論高度,發展到今天已經成為眾所周知的代碼設計經驗的總結。然而,關於設計模式的具體使用,大多數人卻望而生畏,具體原因在於:書上提及的理論往往過於晦澀,讀者只見其結果,卻不明白這樣設計的動機與過程;即,缺乏大型項目實踐的支撐,或者說,沒有經歷一個數十萬行項目的迭代、開發、重構,確實難以理解設計模式的智慧。

  自然,筆者也不敢說有多懂設計模式,只是從一些開源的項目中看見些許設計模式的影子,本文打算不做過多的理論講解,而是直接從Cocos2d-x工程入口的代碼部分嘗試與大家分享其中體現的代理模式。注:筆者使用的Cocos2d-x版本為2.2.6,不能保證3.X版本一樣適用。

  先建立一個最簡單的Hello World項目(具體過程不做闡述,網上可以查看教程),我們找到main函數,代碼如下:

 1 int APIENTRY _tWinMain(HINSTANCE hInstance,
 2                        HINSTANCE hPrevInstance,
 3                        LPTSTR    lpCmdLine,
 4                        int       nCmdShow)
 5 {
 6     UNREFERENCED_PARAMETER(hPrevInstance);
 7     UNREFERENCED_PARAMETER(lpCmdLine);
 8 
 9     // create the application instance
10     AppDelegate app;
11     CCEGLView* eglView = CCEGLView::sharedOpenGLView();
12     eglView->setViewName("Hello World");
13     eglView->setFrameSize(480, 320);
14     return CCApplication::sharedApplication()->run();
15 }

  從 AppDelegate app; 我們看出這是一個代理模式,查看其定義我們看到 class AppDelegate : private cocos2d::CCApplication ,即繼承自CCApplication類。我們先放在一邊,繼續往下看。

  顯然,想要從main函數跳到工程的入口是從 CCApplication::sharedApplication()->run() 這句代碼實現的。其中sharedApplication()是一個單例模式,其內部有一個靜態指針,指針為空則創建對象,不為空則跳過,如此設定以保證多次調用仍然只返回唯一一個單例。當然本文不是講解單例模式,簡單提及一下。下面我們轉入CCApplication的定義,找到如下代碼:

1     // Initialize instance and cocos2d.
2     if (!applicationDidFinishLaunching())
3     {
4         return 0;
5     }

  顯然,這裡便是整個游戲工程的入口。我們考慮,該函數在何處定義?如果 applicationDidFinishLaunching() 是CCApplication類中的成員函數,我們便可以直接調用而無需顧慮。而事實是這樣嗎?我們轉入其定義。看到 bool AppDelegate::applicationDidFinishLaunching() 這樣的代碼。即,真正的實現是在AppDelegate中完成的。然而,我們發現,在CCApplication類中既無定義,也無聲明,那為什麼可以使用?我們看CCApplication類,看到 class CC_DLL CCApplication : public CCApplicationProtocol 這句話,即它是繼承子CCApplicationProtocol。再次跳轉到該函數的定義,我們看到 virtual bool applicationDidFinishLaunching() = 0; ,這是一個純虛函數。何為純虛函數?純虛函數是一種特殊的虛函數,在許多情況下,在基類中不能對虛函數給出有意義的實現,而把它聲明為純虛函數,它的實現留給該基類的派生類去做。在派生類中,若未對該接口進行復寫(OverRide),該派生類依然為純虛基類。顯然,在CCApplication類中並沒有進行復寫,卻可以直接調用該接口。

  回到最上面,我們知道AppDelegate繼承自CCApplication類,在AppDelegate中給出了該函數的定義 virtual bool applicationDidFinishLaunching(); ,這不是一個純虛函數,即,可以對其進行實現。

  回顧一下邏輯,整理如下:

 1 #if 0

8 CCApplicationProtocol //Interface 9 virtual bool applicationDidFinishLaunching() = 0; //定義一個純虛函數的接口 10 11 //各個平台不同的邏輯 12 CCApplication: public CCApplicationProtocol 13 run() 14 { 15 applicationDidFinishLaunching(); //調用該接口 16 } 17 18 AppDelegate: private CCApplication 19 applicationDidFinishLaunching() //實現接口 20 { 21 真正的入口; 22 } 23 24 virtual bool applicationDidFinishLaunching(); 25 26 virtual void applicationDidEnterBackground(); 27 28 virtual void applicationWillEnterForeground(); 29 30 #endif

 

  關於代理模式的優點:

  • 職責清晰,真實的角色就是實現實際的業務邏輯,不用關心其他非本職責的事務,通過後期的代理完成一件完成事務,附帶的結果就是編程簡潔清晰。
  • 代理對象可以在客戶端和目標對象之間起到中介的作用,這樣起到了的作用和保護了目標對象的作用。
  • 高擴展性

  好了,本文到此就要結束了,通過一個具體的工程案例,希望大家對代理模式能學到一些新的內容。關於理論部分就不多做闡述,大家可以去看看《設計模式》這本書。


  注:本文系筆者原創,歡迎轉載,但請注明筆者及出處。另,筆者目前於哈工大計算機學院大四在讀,正在找工作,求職意願為C++開發方向,歡迎私信或郵件聯系。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved