定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象的状态发生变化时,会通知所有观察者对象,常用于事件系统,如键盘输入,鼠标点击等。
// 抽象主题类
public interface ISubject
{
// 添加观察者
void Attach(IObserver observer);
// 移除观察者
void Detach(IObserver observer);
// 通知观察者
void Notify();
}
// 具体主题类
public class ConcreteSubject : ISubject
{
// 保存观察者列表
private List<IObserver> observers = new List<IObserver>();
// 主题的状态
public string State { get; set; }
// 添加观察者
public void Attach(IObserver observer)
{
observers.Add(observer);
}
// 移除观察者
public void Detach(IObserver observer)
{
observers.Remove(observer);
}
// 通知观察者
public void Notify()
{
foreach (var observer in observers)
{
observer.Update(this);
}
}
}
// 抽象观察者类或接口
public interface IObserver
{
// 更新方法,当主题状态改变时被调用
void Update(ISubject subject);
}
// 具体观察者类
public class ConcreteObserver : IObserver
{
// 观察者的名称
public string Name { get; set; }
public ConcreteObserver(string name)
{
this.Name = name;
}
// 更新方法,当主题状态改变时被调用
public void Update(ISubject subject)
{
Console.WriteLine($"{Name}: {subject.State}");
}
}
// 测试代码
class Program
{
static void Main(string[] args)
{
// 创建一个具体主题对象
var subject = new ConcreteSubject();
// 创建两个具体观察者对象
var observer1 = new ConcreteObserver("A");
var observer2 = new ConcreteObserver("B");
// 将观察者添加到主题的观察者列表中
subject.Attach(observer1);
subject.Attach(observer2);
// 改变主题的状态,并通知所有的观察者
subject.State = "Hello";
subject.Notify();
// 移除一个观察者,并再次改变主题的状态,并通知所有的观察者
subject.Detach(observer1);
subject.State = "World";
subject.Notify();
Console.ReadKey();
/*
* 输出结果:
* A: Hello
* B: Hello
* B: World
*/
}
}