观察者模式
观察者模式的核心思想是当一个对象的状态改变时,可以自动的通知其他对象,举个简单的例子,在上学的时候,同桌在偷偷睡觉,然后另一个人望风,若老师过来了,则叫醒睡觉的同学,望风的同学就是观察者。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式是一种对象行为型模式,其主要优点如下。
- 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
- 目标与观察者之间建立了一套触发机制。
它的主要缺点如下。
- 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
- 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
完整代码如下。
using System;
using System.Collections.Generic;
using System.Threading;
namespace _18_Observer
{
/// <summary>
/// 观察者模式
/// </summary>
class Program
{
static void Main(string[] args)
{
//观察者是一种行为设计模式, 允许一个对象将其状态的改变通知其他对象
var subject = new Subject();
var observerA = new ConcreteObserverA();
subject.Attach(observerA);
var observerB = new ConcreteObserverB();
subject.Attach(observerB);
subject.SomeBusinessLogic();
subject.SomeBusinessLogic();
subject.Detach(observerB);
subject.SomeBusinessLogic();
Console.ReadKey();
}
}
public interface IObserver
{
void Update(ISubject subject);
}
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
public class Subject : ISubject
{
public int State { get; set; } = -0;
public List<IObserver> _observers = new List<IObserver>();
public void Attach(IObserver observer)
{
Console.WriteLine("Subject:Attached an observer");
_observers.Add(observer);
}
public void Detach(IObserver observer)
{
_observers.Remove(observer);
Console.WriteLine("Subject:Detached an observer");
}
public void Notify()
{
Console.WriteLine("Subject:Notifying observer...");
foreach (var observer in _observers)
{
observer.Update(this);
}
}
public void SomeBusinessLogic()
{
Console.WriteLine("\nSubject: I'm doing something important.");
State = new Random().Next(0, 10);
Thread.Sleep(15);
Console.WriteLine("Subject: My state has just changed to: " + this.State);
this.Notify();
}
}
class ConcreteObserverA : IObserver
{
public void Update(ISubject subject)
{
if((subject as Subject).State < 3)
{
Console.WriteLine("ConcreteObserverA: Reacted to the event.");
}
}
}
class ConcreteObserverB : IObserver
{
public void Update(ISubject subject)
{
if((subject as Subject).State==0 || (subject as Subject).State >= 2)
{
Console.WriteLine("ConcreteObserverB: Reacted to the event.");
}
}
}
}