Unity遊戲設計模式(二)觀察者模式(Observer Pattern)
阿新 • • 發佈:2019-01-04
最近看遊戲設計模式,當看到觀察者模式時被搞得雲裡霧裡的,什麼觀察者,被觀察者,抽象觀察者,抽象被觀察者。聽著這些詞就覺得可怕,其實理解以後還是比較簡單的。
當我們玩遊戲時,經常會出現一些事件,而這個事件可能會影響到許多個模組時就可以用到觀察者模式。例如:當我們在遊戲中被喪屍咬時,我們就觸發了變身喪屍的特殊事件,此時我們本身的人物模型可能會改變,同時系統的背景音樂和戰鬥方式也可能改變。此時就是一個事件影響多個模組的狀況了,就可以用到觀察者模式,廢話不多說直接上程式碼。
/// <summary> /// 抽象觀察者,定義接收通知的介面 /// </summary> public abstract class Observer { public abstract void OnNotify(); }
首先我們定義一個抽象類Observer,Obserber中我們定義抽象方法,這就是當我們接收到事件時要執行的方法了。
/// <summary> /// 抽象主題(抽象被觀察者)類,內含觀察者列表和實現接收各種通知 /// </summary> public abstract class Subject { private List<Observer> observerList = new List<Observer>(); /// <summary> /// 新增觀察者 /// </summary> /// <param name="observer"></param> public void AddObserver(Observer observer) { observerList.Add(observer); } /// <summary> /// 移除觀察者 /// </summary> /// <param name="observer"></param> public void RemoveObserver(Observer observer) { observerList.Remove(observer); } /// <summary> /// 推送通知 /// </summary> public void Notify() { foreach (Observer o in observerList) { o.OnNotify(); } } }
然後是定義一個抽象主題類,抽象主題類中包含新增和移除Observer的方法,定義一個Notify方法作為推送方法。我們推送訊息到Observer連結串列中的各個Observer方法,Observer方法就開始執行監聽的方法了。
具體主題類是真正實現要推送的訊息,我們確認一個事件是否推送和如何推送訊息的方法等都是在這裡完成的。/// <summary> /// 具體主題(被觀察者)類,實現要推送的主題 /// </summary> public class Boss : Subject { private string _command; public string Command { get { return _command; } set { _command = value; } } }
/// <summary>
/// 觀察者類,當接收到推送通知時,實現各個模組功能
/// </summary>
public class EmployeeA:Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeA(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下達命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
觀察者類,這個是獲取推送訊息時真正要執行的一段程式,在這裡具體化要執行的程式的工作內容。
下面是完整的程式碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class ObserverPattern : MonoBehaviour {
/// <summary>
/// 抽象觀察者,定義接收通知的介面
/// </summary>
public abstract class Observer
{
public abstract void OnNotify();
}
/// <summary>
/// 抽象主題(抽象被觀察者)類,內含觀察者列表和實現接收各種通知
/// </summary>
public abstract class Subject
{
private List<Observer> observerList = new List<Observer>();
/// <summary>
/// 新增觀察者
/// </summary>
/// <param name="observer"></param>
public void AddObserver(Observer observer)
{
observerList.Add(observer);
}
/// <summary>
/// 移除觀察者
/// </summary>
/// <param name="observer"></param>
public void RemoveObserver(Observer observer)
{
observerList.Remove(observer);
}
/// <summary>
/// 推送通知
/// </summary>
public void Notify()
{
foreach (Observer o in observerList)
{
o.OnNotify();
}
}
}
/// <summary>
/// 具體主題(被觀察者)類,實現要推送的主題
/// </summary>
public class Boss : Subject
{
private string _command;
public string Command
{
get { return _command; }
set { _command = value; }
}
}
/// <summary>
/// 觀察者類,當接收到推送通知時,實現各個模組功能
/// </summary>
public class EmployeeA:Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeA(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下達命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
public class EmployeeB : Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeB(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下達命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
public class EmployeeC : Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeC(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下達命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
void Start()
{
Boss boss = new Boss();
EmployeeA employeeA = new EmployeeA(boss);
EmployeeA employeeB = new EmployeeA(boss);
EmployeeA employeeC = new EmployeeA(boss);
employeeA.Name = "僱員A";
employeeA.DoSomething = "打掃衛生";
employeeB.Name = "僱員B";
employeeB.DoSomething = "整理貨物";
employeeC.Name = "僱員C";
employeeC.DoSomething = "清算賬目";
boss.AddObserver(employeeA);
boss.AddObserver(employeeB);
boss.AddObserver(employeeC);
boss.Command = "下達命令";
boss.Notify();
}
}
其實觀察者模式可以這麼理解,我們不妨把它看做是一個超市,具體觀察者是超市的老闆,老闆要下達命令給員工,具體主題是超市的員工,員工收到了老闆下達的命令就開始工作了,抽象主題就是一個任務表,任務表中包含所需要工作員工的名單,我們要告訴名單中的員工你別偷懶了,開始幹活吧,抽象觀察者就是一個工作的大致內容,例如:年底盤查,但是我們不去關心年底盤查具體的步驟該怎麼做,怎麼做的事情由員工自己來負責。