GoF對於Observer的定義為
「在物件之間定一個一對多的的連結方法,當一個物件變換狀態時,其它關連的物件都會自動收到通知」
你也可以這樣說—Observer Objects Observe Observable Objects.(觀察者物件觀察可觀察的物件們)
講個更具體的,你可以想像成自己在Youtube訂閱一個你喜愛的Youtuber,之後你就會在訂閱內容的部分看到對方發出的最新影片,而不用去花費心力去翻閱每一個Youtuber的更新狀況。
而Obsever的實作方式有分成推與拉這兩種,這次會主要以拉的案例為主,有興趣可以點下面的連結看推的例子
IObserver.cs
namespace LinXuan.DesignPattern.Example.Observer
{
public interface IObserver
{
public void ObserverUpdate();
}
}
ISubject.cs
namespace LinXuan.DesignPattern.Example.Observer
{
public interface ISubject
{
public void Attach(IObserver observer);//想要訂閱此Observer時,就將其記錄下來
public void Detach(IObserver observer);//取消訂閱
public void Notify();//更新擁有的訂閱者
}
}
Observers.cs
using UnityEngine;
namespace LinXuan.DesignPattern.Example.Observer
{
public class FooObserver : IObserver
{
private string m_ObjectState;
private FooSubject m_Subject = null;
public FooObserver(FooSubject fooSubject)
{
m_Subject = fooSubject;
}
public void ObserverUpdate()
{
Debug.Log("FooObserver.Update");
}
public void ShowState() //當呼叫此function時才顯示當前狀態
{
Debug.Log("FooObserver: Subject " + m_ObjectState);
}
}
public class BarObserver : IObserver
{
private FooSubject m_Subject = null;
public BarObserver(FooSubject fooSubject)
{
m_Subject = fooSubject;
}
public void ObserverUpdate()
{
Debug.Log("BarObserver.Update");
Debug.Log("BarObserver: Subject " + m_Subject.GetState()); //在這邊就顯示當前狀態
}
}
}
FooSubject.cs
using System.Collections.Generic;
namespace LinXuan.DesignPattern.Example.Observer
{
public class FooSubject : ISubject
{
List<IObserver> m_Observers = new List<IObserver>(); //儲存想要關注的Observer的地方
string m_SubjectState;
public void SetState(string state)
{
m_SubjectState = state;
Notify();
}
public string GetState()
{
return m_SubjectState;
}
public void Attach(IObserver observer)
{
m_Observers.Add(observer);
}
public void Detach(IObserver observer)
{
m_Observers.Remove(observer);
}
public void Notify()
{
foreach (IObserver observer in m_Observers)
{
observer.ObserverUpdate();
}
}
}
}
ObserverTest_PullTest.cs
using UnityEngine;
namespace LinXuan.DesignPattern.Example.Observer
{
public class ObserverTest_PullTest : MonoBehaviour
{
private void Start()
{
FooSubject fooSubject = new FooSubject();
FooObserver fooObserver = new FooObserver(fooSubject);
BarObserver barObserver = new BarObserver(fooSubject);
fooSubject.Attach(fooObserver);
fooSubject.Attach(barObserver);
fooSubject.SetState("Subject state 1.");
fooObserver.ShowState();
}
}
}
輸出如下
Push, pull mechanism observer pattern
The Observer Pattern
設計模式與遊戲開發的完美結合(暢銷回饋版)