如果兩塊代碼耦合,意味著你必須同時(shí)了解這兩塊代碼。如果你讓他們解耦,那么你只需要了解其一。觀察者模式便是專為實(shí)現(xiàn)它而誕生的:“在對(duì)象間定義一種一對(duì)多的依賴關(guān)系,以便當(dāng)某對(duì)象狀態(tài)改變時(shí),與它存在依賴關(guān)系的所有對(duì)象都能收到通知并自動(dòng)進(jìn)行更新”。大家一定都聽(tīng)說(shuō)過(guò)一直很流行的MVC框架,其底層就是觀察者模式。觀察者模式應(yīng)用十分廣泛,在游戲中善用觀察者模式,可以讓你的代碼更加“純凈”。
假設(shè)你現(xiàn)在在維護(hù)一個(gè)橫版動(dòng)作游戲,主角的任務(wù)就是一路砍殺,最終虐殺BOSS。殺敵的路上充滿了坎坷,為了對(duì)玩家更加友好,策劃要求主角在打破一個(gè)木桶時(shí),在UI界面上給出一句提示“打破所有木桶即可開(kāi)啟密道”。類似的需求可能有很多,戰(zhàn)斗系統(tǒng)的各種特殊狀況都可能需要UI界面的配合,但是我們真的要直接把UI顯示的代碼加入戰(zhàn)斗系統(tǒng)嗎?答案是否定的,如果我們這樣做顯然會(huì)增加UI系統(tǒng)和戰(zhàn)斗系統(tǒng)的耦合,下次再去修改一個(gè)UI的時(shí)候,你很可能就要去先去看看為什么戰(zhàn)場(chǎng)里的怪物會(huì)追著你不放了。這時(shí)候觀察者模式就派上用場(chǎng)了,它使得戰(zhàn)場(chǎng)能夠發(fā)出一個(gè)消息,并通知對(duì)消息感興趣的對(duì)象,而不用關(guān)心是誰(shuí)收到了通知。
大致是下面這個(gè)樣子:
void MoveableObject::OnAttack(AttackParameters& stAttackParameters)
{
CalAttack(stAttackParameters); if (m_iMyHp <= 0 && m_iType == OBJECT_TYPE::WOOD)
{
notify(stAttackParameters.m_pFighter, EVENT_WOOD_DEAD);
}
}