C#中的观察者模式
- 观察者模式介绍
- 当有一对多的依赖关系的时候,比如一个主题的状态发生改变,需要其他的对象做出相应的变化的时候,就可以用到观察者模式
- 观察者模式,有一个抽象观察类和一个抽象主题类,观察类有对主题状态改变所要做出的反应,而主题类需要通知每个注册了主题的对象进行反应。
- 总的来说,就是将主题类和观察类进行抽象化,使各个具体的主题以及观察类之间没有耦合,当需要增加主题或者观察者,甚至增加具体主题类或者观察类的时候,都不需要产生具体类之间的耦合,它可以实现对扩展开放对修改封闭的原则。
- 观察者模式演示
/// <summary>
/// 抽象主题类
/// </summary>
public abstract class Subject
{
private List<Observer> observers;
public Subject()
{
this.observers = new List<Observer>();
}
protected void Notify()
{
foreach (var item in observers)
{
item.Response();
}
}
public void Register(Observer ob)
{
observers.Add(ob);
}
}
/// <summary>
/// 具体主题类,世界卫生组织
/// </summary>
public class WHO : Subject
{
public void Warning()
{
Console.WriteLine("新冠病毒传染性强,注意防范!!!");
Notify();
}
}
/// <summary>
/// 抽象观察类
/// </summary>
public abstract class Observer
{
public abstract void Response();
}
/// <summary>
/// 具体观察类,中国
/// </summary>
public class China : Observer
{
public override void Response()
{
Console.WriteLine("中国:");
Console.WriteLine("全民带口罩");
Console.WriteLine("认真落实防疫策略");
Console.WriteLine("帮助他国共同战疫");
}
}
/// <summary>
/// 具体观察类,美国
/// </summary>
public class America : Observer
{
public override void Response()
{
Console.WriteLine("特朗普:");
Console.WriteLine("我们做的很好");
Console.WriteLine("死亡人数在20万以内");
Console.WriteLine("注射消毒水消灭病毒");
}
}
客户端调用
static void Main(string[] args)
{
WHO who = new WHO();
China china = new China();
America american = new America();
who.Register(china);
who.Register(american);
who.Warning();
Console.Read();
}
- 当需要再增加其他国家的时候,新建一个类实现Observer,在WHO那里注册一下,一并通知,并不需要修改核心业务逻辑。
- 但是,在这里也有一个缺点就是,我们对不同的主题做出的反应都只能是一个,如果需要做出不同的反应,可以使用事件,当需要进行通知的时候,手动注册一下各个观察者的反应事件,不过这样的话,虽然没有修改抽象层的业务逻辑,但是在客户端调用时要对每个观察者的反应事件进行修改也是比较麻烦的。而且,在多线程环境下,如果有多个主题,且同时对该事件进行修改,会有意料之外的效果。