观察者模式(Observer Pattern)

模式定义

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

UML类图

  • 观察目标(Subject) 也称被观察的对象,有观察者类型集合字段,并提供订阅Attach(Observer observer)和取消订阅方法Detach(Observer observer),以及通知观察者方法Notify()
  • 具体观察目标(ConcreteSubject) 目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,调用通知方法。
  • 观察者(Observer) 定义对观察目标的改变做出操作Update()抽象方法
  • 具体观察者(ConcreteObserver) 实现抽象观察者角色接口,(如果需要目标类更多信息,则需要依赖具体目标类)

代码结构

	public class ObserverApp
	{
		public void Run()
		{
			ConcreteSubject s = new ConcreteSubject();

			s.Attach(new ConcreteObserver() { Subject = s, Name = "X" });
			s.Attach(new ConcreteObserver() { Subject = s, Name = "Y" });
			s.Attach(new ConcreteObserver() { Subject = s, Name = "Z" });

			s.SubjectState = "ABC";
			s.Notify();
		}
	}

	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();
			}
		}
	}

	class ConcreteSubject : Subject
	{
		public string SubjectState { get; set; }
	}

	abstract class Observer
	{
		public abstract void Update();
	}

	class ConcreteObserver : Observer
	{
		public string Name { get; set; }
		public ConcreteSubject Subject { get; set; }

		public override void Update()
		{
			string state = this.Subject.SubjectState;
			Console.WriteLine("Observer {0}'s new state is {1}",this.Name,state);
		}
	}

情景案例

现在大家最关心的应该是回家过年的火车票,相信大家电脑上也安装了些刷票的软件吧!这样才能安心工作,等有票了自动通知。

public class ObserverApp
	{
		public void Run()
		{
			Ticket360 s = new Ticket360();

			s.Attach(new ConcreteCustomer() { Subject = s, Name = "小王" });
			s.Attach(new ConcreteCustomer() { Subject = s, Name = "小赵" });
			s.Attach(new ConcreteCustomer() { Subject = s, Name = "小孙" });

			s.TicketState = "有坐票";
			s.Notify();
		}
	}

	/// <summary>
	/// 火车票
	/// </summary>
	abstract class Ticket
	{

		private List<Customer> _observers = new List<Customer>();

		public void Attach(Customer observer)
		{
			_observers.Add(observer);
		}

		public void Detach(Customer observer)
		{
			_observers.Remove(observer);
		}

		public void Notify()
		{
			foreach (Customer o in _observers)
			{
				o.Notify();
			}
		}
	}

	class Ticket360 : Ticket
	{
		public string TicketState { get; set; }
	}

	abstract class Customer
	{
		public abstract void Notify();
	}

	class ConcreteCustomer : Customer
	{
		public string Name { get; set; }
		public Ticket360 Subject { get; set; }

		public override void Notify()
		{
			string state = this.Subject.TicketState;
			Console.WriteLine("{0}顾客关注的火车票现在状态为 {1}", this.Name, state);
		}
	}

C#中的优化

在C#中其实可以通过delegateEvent,可参数传递函数,更方便的实现观察者模式。

原文地址:https://www.cnblogs.com/LoveTomato/p/8447099.html