设计模式之 Observer Pattern观察者模式
观察者模式
Observer
Observer模式为组件向相关接收方【广播】消息提供了灵活的方法;
该模式定义了对象一到多的依赖关系,这样当对象改变状态时,将自动通知并更新他所有的依赖对象;
优点
抽象了主体与Observer之间的耦合关系;
支持广播方式的通信
适用
对一个对象的修改涉及其他对象的修改,而且不知道有多少对象需要进行修改;
对象应该能够在不用假设对象标识的前提下,通知其他对象;
示例代码
/// <summary>
/// 数字生成器类
/// </summary>
public class NumberGenerator
{
/// <summary>
/// 存储随机生成的数字
/// </summary>
public int Number { get; private set; }
/// <summary>
/// 存储观察者
/// </summary>
private List<Observer> observers = new List<Observer>();
/// <summary>
/// 添加(注册)观察者
/// </summary>
/// <param name="observer"></param>
public void AddObserver(Observer observer) => observers.Add(observer);。
/// <summary>
/// 删除(取消注册)观察者
/// </summary>
/// <param name="observer"></param>
public void RemoveObserver(Observer observer) => observers.Remove(observer);
/// <summary>
/// 通知观察者,也就是逐个调用所有观察者的方法
/// </summary>
private void NotifyObservers()
{
foreach (var o in observers)
{
o.Update(this);
}
}
/// <summary>
/// 随机生成数字
/// </summary>
public void Execute()
{
Random r = new Random();
while (true)
{
Number = r.Next(1, 10);
NotifyObservers();
}
}
}
/// <summary>
/// 观察者接口
/// </summary>
public interface Observer
{
void Update(NumberGenerator numberGenerator);
}
/// <summary>
/// 数字观察者,打印数字
/// </summary>
public class DigitalObserver : Observer
{
public void Update(NumberGenerator numberGenerator)
{
Console.WriteLine($"更新数字:{numberGenerator.Number}");
Thread.Sleep(100);
}
}
/// <summary>
/// 图形观察者,按数字打印对应个数的符号
/// </summary>
public class GraphObserver : Observer
{
public void Update(NumberGenerator numberGenerator)
{
Console.Write("更新符号:");
for (int i = 0; i < numberGenerator.Number; i++)
{
Console.Write("*");
Thread.Sleep(100);
}
Console.WriteLine();
}
}
/// <summary>
/// 观察者模式 测试函数
/// </summary>
public static void ObserverPatternTest()
{
//数字生成器
NumberGenerator generator = new NumberGenerator();
//创建观察者对象
DigitalObserver digitalObserver = new DigitalObserver();
GraphObserver graphObserver = new GraphObserver();
//添加(注册)观察者对象
generator.AddObserver(digitalObserver);
generator.AddObserver(graphObserver);
//执行(生成随机数,并通知观察者进行打印)
generator.Execute();
}