這次來比較兩個有趣的東西:Strategy和Decorator
同樣是巢狀邏輯判斷式的寫法
改法不止限於上次提到的Composed
Strategy和Decorator也是不錯的選擇
艾倫史密斯在互動元件那邊做了一個示範
詳細內容我不贅述了,有興趣可以去找找看
總之是在處理主角吸上互動元件後
怎麼對主角施予重力和建立Joint
讓主角不會掉下來,並且可以做有限制的移動
第一個碰到的問題是
當主角踩在互動元件上面的那一瞬間
要怎麼去判斷他踩到的是什麼呢?
想當然爾,碰撞會有碰撞訊息
於是以下的Code就會出現:
switch (pMsg->m_uiType)
{
case MST_TRIGGER_COLLISION:
{
ksMsgActor *pObj = pMsg->m_pTouchAI;
if ( NiIsKindOf(ksObjA, pObj) || NiIsKindOf(ksObjB, pObj) )
// 建立第一種Joint
else if ( NiIsKindOf(ksObjC, pObj) || NiIsKindOf(ksObjD, pObj) )
// 建立第二種Joint
else if ( NiIsKindOf(ksObjE, pObj) )
// 建立第三種Joint
else if ( NiIsKindOf(ksObjF, pObj) )
// 建立第四種Joint
break;
}
}
很好,決定了Joint的種類
接下來主角開始移動,但是磁力物件千百種
有的直有的彎,怎麼知道主角該不該轉彎呢?
主角吸在物件上面,所以會有Trigger的訊息
於是下列的程式碼出現:
switch (pMsg->m_uiType)
{
case MST_TRIGGER_ON_STAY:
{
ksMsgActor *pObj = pMsg->m_pTouchAI;
if ( NiIsKindOf(ksObjA, pObj) || NiIsKindOf(ksObjB, pObj) )
// 走在直線型的物件上
else if ( NiIsKindOf(ksObjC, pObj) || NiIsKindOf(ksObjD, pObj) )
// 走在圓弧形的物件上
break;
}
}
如果你以為艾倫史密斯是這種寫法,那你就錯了
要知道,他可是史密斯
寫法當然要不一樣,所以他採取的是Strategy
一種抽象到不行的寫法,害我每次Trace Code都很痛苦...
不過這真的是物件抽象的極致
搞到最後他也不知道是碰到哪一個種類的物件~XD
使用Strategy,可以大大減少主角這邊判斷的機制
我只需要呼叫統一的介面,就可以輕鬆吸上磁力物件
就像這樣:
ksTerrainDestKit* pKit = (ksTerrainDestKit*)pAI->GetKit(TERRAIN_DEST_KIT);
pKit->CreateJoint();
這裡的CreateJoint裡面包著就是Strategy function
同理,主角移動時也用類似的方式來取得資料:
pKit->AddForce();
剩下的由物件自己去處,而ksTerrainDestKit就是Strategy委託者
那麼Decorator何時會使用呢?
對我來說,如果Strategy是橫向的封裝
那Decorator就是縱向的封裝
Strategy會依據種類來決定使用哪一種function
但是Decorator是一層一層的
封裝多少層,就會經過多少個function
兩個Pattern詳細比較在豬屎排程寫的比較多
但是真正要使用的時刻,怎麼判斷用哪一個
還真的是靠個人修行!
講了那麼多,其實兩種Pattern的比較只講了一點點...
好吧,我承認自己修行不夠,沒法寫出精闢的解析
所以就讓我繼續下一章節吧!XD
- Aug 29 Fri 2008 02:50
Refactoring to Patterns~Simplification~Strategy V.S Decorator
close
全站熱搜
留言列表
發表留言