观察者模式介绍
定义对象之间的一对多依赖关系,当一个对象改变状态时,它的所有依赖关系都会被自动通知和更新。
观察者模式
//
// (参与者)
//--------------------------------
//参与该模式的类和对象是:
//
// 主题
//了解观察者,任何数量的观察者对象都可以观察一个主体
//提供一个连接和分离Observer对象的接口。
// ConcreteSubject
//为ConcreteObserver存储感兴趣的状态
//当它的状态改变时发送一个通知给它的观察者
// 观察者
//为对象定义一个更新接口,这些对象应该在主题的更改时得到通知。
// ConcreteObserver
//维护一个concretesobject对象的引用
//存储与主题保持一致的状态
//实现Observer更新接口,以保持其状态与主体的一致
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ObserverStructure : MonoBehaviour
{
void Start()
{
// Configure Observer pattern
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s, "X"));
s.Attach(new ConcreteObserver(s, "Y"));
s.Attach(new ConcreteObserver(s, "Z"));
// Change subject and notify observers
s.SubjectState = "ABC";
s.Notify();
// Change subject and notify observers again
s.SubjectState = "666";
s.Notify();
}
}
/// <summary>
/// The 'Subject' abstract class
/// </summary>
abstract class Subject
{
private List<Observer> _observers = new List<Observer>();
public void Attach(Observer observer)
{
_observers.Add(observer);
}
public void Detach(Observer observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach (Observer o in _observers)
{
o.Update();
}
}
}
/// <summary>
/// The 'ConcreteSubject' class
/// </summary>
class ConcreteSubject : Subject
{
private string _subjectState;
// Gets or sets subject state
public string SubjectState
{
get { return _subjectState; }
set { _subjectState = value; }
}
}
/// <summary>
/// The 'Observer' abstract class
/// </summary>
abstract class Observer
{
public abstract void Update();
}
/// <summary>
/// The 'ConcreteObserver' class
/// </summary>
class ConcreteObserver : Observer
{
private string _name;
private string _observerState;
private ConcreteSubject _subject;
// Constructor
public ConcreteObserver(
ConcreteSubject subject, string name)
{
this._subject = subject;
this._name = name;
}
public override void Update()
{
_observerState = _subject.SubjectState;
Debug.Log("Observer "+ _name+"'s new state is "+_observerState);
}
// Gets or sets subject
public ConcreteSubject Subject
{
get { return _subject; }
set { _subject = value; }
}
}
观察者模式案例1
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//该实际代码演示了观察者模式,在该模式中,每次股票变化时都会通知注册投资者
namespace ObserverExample1
{
public class ObserverExample1 : MonoBehaviour
{
void Start()
{
// Create IBM stock and attach investors
//创建IBM股票并吸引投资者
IBM ibm = new IBM("IBM", 120.00);
ibm.Attach(new Investor("Sorros"));
ibm.Attach(new Investor("Berkshire"));
// Fluctuating prices will notify investors
ibm.Price = 120.10;
ibm.Price = 121.00;
ibm.Price = 120.50;
ibm.Price = 120.75;
}
}
/// <summary>
/// The 'Subject' abstract class
/// </summary>
abstract class Stock
{
private string _symbol;
private double _price;
private List<IInvestor> _investors = new List<IInvestor>();
// Constructor
public Stock(string symbol, double price)
{
this._symbol = symbol;
this._price = price;
}
/// <summary>
/// 链接观察者
/// </summary>
/// <param name="investor"></param>
public void Attach(IInvestor investor)
{
_investors.Add(investor);
}
/// <summary>
/// 分离观察者
/// </summary>
/// <param name="investor"></param>
public void Detach(IInvestor investor)
{
_investors.Remove(investor);
}
public void Notify()
{
foreach (IInvestor investor in _investors)
{
investor.Update(this);
}
Debug.Log("Stock Notify( ) called");
}
// Gets or sets the price
public double Price
{
get { return _price; }
set
{
if (_price != value)
{
_price = value;
Notify();
}
}
}
// Gets the symbol
public string Symbol
{
get { return _symbol; }
}
}
/// <summary>
/// The 'ConcreteSubject' class
/// 具体主题
/// </summary>
class IBM : Stock
{
// Constructor
public IBM(string symbol, double price)
: base(symbol, price)
{
}
}
/// <summary>
/// The 'Observer' interface
/// 投资者
/// </summary>
interface IInvestor
{
void Update(Stock stock);
}
/// <summary>
/// The 'ConcreteObserver' class
/// 具体观察者
/// </summary>
class Investor : IInvestor
{
private string _name;
private Stock _stock;
// Constructor
public Investor(string name)
{
this._name = name;
}
public void Update(Stock stock)
{
//Debug.Log("Notified {0} of {1}'s " +"change to {2:C}", _name, stock.Symbol, stock.Price);
Debug.Log("Notified "+ _name+" of "+ stock+"'s " + "change to "+stock.Price);
}
// Gets or sets the stock
public Stock Stock
{
get { return _stock; }
set { _stock = value; }
}
}
}