設計模式在遊戲開發中的應用之觀察者模式
阿新 • • 發佈:2019-01-07
觀察者模式
1.通俗的定義
觸發事件的一方不關心誰來處理,處理事件的一方不關心事件是從哪裡來的。觀察者模式就是讓觀察者與被觀察者徹底解耦。
2.2.結構圖如下(圖片來源與網路):
3.遊戲開發中的使用
當我們設計一個成就係統的時候,往往要在各個系統都要增加判斷,比如殺死某種怪物多少隻,新手往往可能這麼寫:
如果這樣寫下去,後果將不堪設想:各個類直接將會超級耦合,成就判斷將會蔓延到整個專案的每個角落!觀察者模式就是為了解決這個問題而出現的。觀察者模式讓程式碼徹底解耦,還是上面的那個例子:public static KILL_1009_COUNT = 0; main () { //killMonster是殺死一個怪物,返回殺死怪物的id int id = killMonster(); //如果殺死的怪物是1009那麼數量加一,超過100次達成成就 if (id == "1009") { KILL_1009_COUNT++; if (KILL_1009_COUNT > 100) { print("達成成就!殺死1009怪物100次!"); } } }
main () {
//killMonster是殺死一個怪物,返回殺死怪物的id
int id = killMonster();
//傳送訊息,殺死怪物,並將殺死的怪物id一起傳送
notify(EVENT_KILL_MONSTER, id);
}
這樣程式碼的各個功能就不用關心成就相關的邏輯,只是通知我做了這樣一件事情就可以了。同樣,遊戲中這樣的例子到處都是,比如增加經驗時,我們傳送增加經驗的訊息,接收訊息的地方來處理到底升沒升級,因為可以增加經驗的地方有很多,這樣我們就不用匯出判斷是否升級了。下面看一下觀察者的實現:
然後在寫一個成就管理類來管理各種成就觀察者,這樣各個成就直接也可以解耦。//處理觀察者與被觀察者 class Notification { //一個可變的觀察者列表 private List observerList = null; //該類是單例(後面我們會單獨講單例模式) private static Notification _instance = null; public static getInstance() { if (_instance == null) { _instance = new Notification(); //初始化列表容器 observerList = new ArrayList(); } return _instance; } //新增觀察者 public void addObserver(Observer obs) { if (!observerList.isExistobs { observerList.add(obs); } } //刪除觀察者 public void removeObserver(Observer obs) { observerList.remove(obs); } //廣播訊息 public void sendMsg(String event, ..) { for (Observer obs : observerList) { if (obs.event == event) { obs.onNotify(..); } } } } //觀察者基類 class Observer { String event; //接收訊息函式,event是訊息型別,後面是引數 void onNotify(..) //新增觀察者 void addObserver(String event) { event = event; Notification.getInstance().addObserver(this); } } //殺怪成就觀察者 class AchievementObserver extends Observer { void onNotify(id) { if (id == 1009) { //處理殺1009怪的成就邏輯 } else if (id == 1010) { //處理殺1010怪的成就邏輯 } } } main () { //killMonster是殺死一個怪物,返回殺死怪物的id int id = killMonster(); //傳送訊息,殺死怪物,並將殺死的怪物id一起傳送 Notification.getInstance().sendMsg(EVENT_KILL_MONSTER, id); }
其他問題:
1.引用銷燬問題:這個問題容易造成記憶體洩漏,就是在這個觀察者不再使用時,一定記得將其remove,否則這個觀察者一直在引用著,不會被釋放。
2.同步非同步問題:sendMsg這個函式中是在主執行緒按加入順序進行傳送的,在特殊情況下根據需要可以使用多執行緒來實現。
3.其他應用:觀察者模式在MVC這種結構下也經常使用,control來處理邏輯,通過觀察者來相應UI事件。
觀察者模式的優點就是可以做到完全的解耦;缺點就是使用不當會讓程式難以維護和除錯。
關注我的公眾號Ituuz_coder,第一時間推送新文章: