C#设计模式之观察者模式

这篇具有很好参考价值的文章主要介绍了C#设计模式之观察者模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

观察者(Observer)模式也称发布-订阅(Publish-Subscribe)模式,定义了对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式的图解如下所示:

Subject(目标):

目标知道它的观察者。可以有任意多个观察者观察同一个目标。

目标提供了注册和删除观察者对象的接口。

Observer(观察者):

为那些在目标发生改变时需获得通知的对象定义一个更新接口。

ConcreteSubject(具体目标):

将有关状态存入各ConcreteObserver对象。

当它的状态发生改变时,向它的各个观察者发出通知。

ConcreteObserver(具体观察者):

维护一个指向ConcreteSubject对象的引用。

存储有关状态,这些状态应与目标的状态保存一致。

实现Observer的更新接口以使自身状态与目标的状态保持一致。

不使用事件的示例

接下来我将根据上面的图解写一个C#观察者模式的例子,刚开始这个例子没有使用事件,在后面一个例子中使用事件。

首先来看看Subject(目标):

 //主题接口
 public interface ISubject
 {
     public void Attach(Observer observer);
     public void Detach(Observer observer);
     public void Notify();
     public string? SubjectState { get; set; }

 }

这里我使用的是接口,里面有Attach、Detach和Notify方法的声明,还有SubjectState属性的声明。

接下来看看ConcreteSubject(具体目标):

 public class School : ISubject
 {
     private IList<Observer> observers = new List<Observer>();
     public string? SubjectState { get; set; }
     public void Attach(Observer observer)
     {
         observers.Add(observer);
     }
     public void Detach(Observer observer)
     {
         observers.Remove(observer);
     }
     public void Notify()
     {
         foreach (var observer in observers)
         {
             observer.Update();
         }
     }
 }

这里我以学校发通知为例,School类实现了ISubject接口,有一个观察者的列表,在Attach方法中添加一个观察者,在Detach方法中移除一个观察者。在Notify方法中遍历观察者的列表,让每一个观察者都执行Update方法。

现在来看看Observer(观察者):

 public abstract class Observer
 {
     protected string? name;
     protected ISubject? subject;
     public Observer(string name,ISubject subject)
     {
         this.name = name;
         this.subject = subject;
     }
     public abstract void Update();
 }

这是一个抽象类,包含有一个抽象的Update方法。

再看看ConcreteObserver(具体观察者):

 public class Student : Observer
 {
     public Student(string name,ISubject subject) : base(name,subject) 
     { 

     }
     public override void Update() 
     {
         Console.WriteLine($"{name}接收到来自学校的通知:{subject?.SubjectState},
                           时间:{DateTime.Now}\r\n");
     }
 }

这里我以学生接收来自学校的消息为例,Student类继承自Observer抽象类,并重写了Update方法。

最后来看看怎么使用观察者模式:

 static void Main(string[] args)
 {
     School school = new School();
     Student student1 = new Student("小王", school);
     Student student2 = new Student("小明", school);
     Student student3 = new Student("小红", school);

     school.Attach(student1);
     school.Attach(student2);
     school.Attach(student3);

     school.SubjectState = "学校放假了";
     school.Notify();
    
     school.Detach(student3);

     Task.Delay(3000).Wait();

     school.SubjectState = "学校开学了";
     school.Notify();
     Console.ReadLine();

 }

创建一个School对象,三个Student对象。

     school.Attach(student1);
     school.Attach(student2);
     school.Attach(student3);

表示将student1、student2、student3添加到school中的观察者列表中。

 school.SubjectState = "学校放假了";
 school.Notify();

设置school中SubjectState属性的值,然后调用school的Notify方法。

 school.Detach(student3);

将student3从school的观察者列表中移除。

Task.Delay(3000).Wait();

等待3秒。

 school.SubjectState = "学校开学了";
 school.Notify();
 Console.ReadLine();

重新设置school中SubjectState属性的值,然后再调用school的Notify方法。

运行结果如下所示:

学校放假了,小王、小明和小红都接收到了学校的通知。由于后面小红被移出了观察者列表,因此学校开学了的消息小红没有接收到。

使用事件的示例

C#中可以通过事件来使用观察者模式,接下来我将以一个示例加以说明。

自定义事件数据类:

 public class SendMessageArgs : EventArgs
 {
     public string? Message { get; set; }
     public DateTime DateTime { get; set; }
     public SendMessageArgs(string? message)
     {
         Message = message;
         DateTime = DateTime.Now;
     }
 }

Person类:

 public class Person
 {
     public string? Name { get; set; }
     public event EventHandler<SendMessageArgs>? SendMessageEvent;
     public Person(string? name)
     {
         Name = name;
     }
     public void SendMessage(string message) 
     { 
         SendMessageArgs sendMessageArgs = new SendMessageArgs(message); 
         
         SendMessageEvent?.Invoke(this, sendMessageArgs);
     }
     public void ShowMessage(object? sender,SendMessageArgs e)
     {
         Person? person = (Person?)sender;
         Console.WriteLine($"{this.Name}:收到来自{person?.Name}的消息:{e.Message},时间:{e.DateTime}\r\n");
     }
     public void Subscribe(Person person)
     {
         person.SendMessageEvent += ShowMessage;
     }
     public void UnSubscribe(Person person)
     {
         person.SendMessageEvent -= ShowMessage;
     }
 }

Person类中的SendMessage方法会触发事件,ShowMessage方法是事件处理程序,Subscribe方法可以订阅事件,UnSubscribe方法可以取消订阅事件。

现在来看看是怎么使用:

static void Main(string[] args)
{
    Person Trump = new Person("川普");
    Person Biden = new Person("拜登");

    Person person1 = new Person("person1");
    Person person2 = new Person("person2");
    Person person3 = new Person("person3");

    person1.Subscribe(Trump);
    person2.Subscribe(Trump);
    person3.Subscribe(Trump);

    person1.Subscribe(Biden);

    Trump.SendMessage("Nobody knows ... better than me!!!");

    Task.Delay(2000).Wait();

    Biden.SendMessage("I don't believe it!!!");

    person3.UnSubscribe(Trump);

    Task.Delay(2000).Wait();

    Trump.SendMessage("Make ... Great Again!!!");
    Console.ReadLine();          
}

创建了5个Person对象,分别为Trump、Biden、person1、person2、person3。

person1、person2、person3订阅了Trump,person1订阅了Biden。

Trump发了一条消息,然后过了2秒,Biden也发了一条消息。

person3不再订阅Trump,过了2秒,Trump又发消息了。

运行结果如下所示:

由于person1、person2、person3订阅了Trump,所以可以收到来自Trump的消息。

由于person1订阅了Biden,所以可以收到来自Biden的消息。

后面person3退订了Trump,所以只有person1、person2能收到来自Trump的消息。

总结

以上使用C#分别创建了不通过事件与通过事件的示例,介绍了在C#中如何使用观察者模式,希望对你有所帮助。

参考

1、《Head First 设计模式(中文版)》

2、《大话设计模式》

3、《设计模式:可复用面向对象软件的基础》

4、YouTube [Design Patterns: C# Pub-Sub Simple Twitter example]文章来源地址https://www.toymoban.com/news/detail-777000.html

到了这里,关于C#设计模式之观察者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——观察者模式

    观察者模式可以分为观察者和被观察者,观察者通过注册到一个被观察者中,也可视为订阅,当被观察者的数据发生改变时,会通知到观察者,观察者可以据此做出反应。 可以类比订阅报纸,报社就是被观察者,订阅者就是观察者,订阅者通过订阅报纸与报社建立联系,而报

    2024年02月15日
    浏览(53)
  • 设计模式-观察者模式

    观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者

    2024年02月15日
    浏览(58)
  • 设计模式---观察者模式

    1,概念         属于行为模式的一种,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一对象主题对象,这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 在观察者模式中有如下角色: Subject:抽象主题(抽象被观察者),

    2024年02月15日
    浏览(65)
  • 设计模式:观察者模式

    定义 观察者模式(Observer Pattern)是一种行为设计模式,允许一个对象(称为“主题”或“可观察对象”)维护一组依赖于它的对象(称为“观察者”),当主题的状态发生变化时,会自动通知所有观察者对象。 应用场景 观察者模式适用于以下场景: 联动反应 :当一个对象

    2024年04月08日
    浏览(59)
  • 重温设计模式 --- 观察者模式

    观察者模式 是一种行为型设计模式,它允许对象之间建立一种一对多的关系,使得当一个对象状态改变时,所有依赖它的对象都能够自动得到通知并更新自己的状态。该模式可以帮助我们实现松耦合的系统,以便更好地应对变化和扩展。 在观察者模式中,有两个角色: 观察

    2024年02月13日
    浏览(59)
  • 设计模式(11)观察者模式

    一、概述: 1、定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 2、结构图: 实现  调用

    2024年02月11日
    浏览(53)
  • 设计模式——14. 观察者模式

    观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都能够自动收到通知并更新自己的状态,以保持与被观察对象的同步。观察者模式也被称为发布-订阅模式。 观察者模式包含以

    2024年02月07日
    浏览(45)
  • 设计模式之观察者模式

    可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。 从报纸和杂志的订阅说起: 报社的业务就是出版报纸 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。 当你不

    2024年01月24日
    浏览(54)
  • 观察者设计模式

    行为型模式(Behavioral Patterns):这类模式主要关注对象之间的通信。它们 分别是: 职责链模式(Chain of Responsibility) 命令模式(Command) 解释器模式(Interpreter) 迭代器模式(Iterator) 中介者模式(Mediator) 备忘录模式(Memento) 观察者模式(Observer) 状态模式(State) 策略

    2024年01月24日
    浏览(51)
  • 设计模式-观察者

    观察者模式是一种广泛应用于软件开发中的行为设计模式,尤其是在面向对象编程(OOP)中。该模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新 在观察者模式中,存在两个主要角色: 主题(Subject) 或 被

    2024年01月22日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包