《C# .net软件筹划模式-----观察者模式》

[复制链接]
发表于 2026-2-9 14:51:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
观察者模式(Observer Pattern)是一种‌软件筹划模式‌,属于对象活动模式的一种。它界说了一种‌一对多的依靠关系‌,使得多个观察者对象可以同时监听某个主题对象(也称被观察者)。当主题对象的状态发生改变时,会主动关照全部注册的观察者,让它们可以或许主动更新自身状态。‌

这种模式的焦点在于‌解耦‌:主题对象无需知道具体有哪些观察者,只需维护一个观察者列表并在状态厘革时关照它们;而观察者也只需关注本身感爱好的变乱,无需主动轮询主题状态。‌

观察者模式在软件架构中被广泛应用,尤其实用于‌变乱处理惩罚体系‌、‌用户界面与业务数据的同步‌、‌权限管理‌等场景。比方,在图形界面中,界面元素(观察者)可以监听配景数据模子(主题)的厘革,一旦数据更新,界面主动革新。‌

重要脚色


  • 主题(Subject):也称为被观察者,它是一个具体的对象,通过attach()方法注册观察者,通过notifyObservers()方法关照观察者。
  • 观察者(Observer):也称为观察者,它界说了一个更新接口,当主题状态改变时,得到关照并举行相应的处理惩罚。
  • 具体主题(ConcreteSubject):是主题的具体实现对象,它生存着观察者对象的列表,并实现了抽象主题中的方法。
  • 具体观察者(ConcreteObserver):是观察者的具体实现对象,它存储着具体主题的引用,实现了抽象观察者中的更新接口。


推模式与拉模式

在关照机制上,观察者模式通常分为两种实现方式:

  • ‌推模式(Push)‌:主题对象将状态数据‌主动推送‌给观察者,观察者无需额外获取。
  • ‌拉模式(Pull)‌:主题仅发送关照,观察者‌主动拉取‌所需数据,通常通过主题对象的引用获取最新状态。‌
观察者模式也常被称为‌发布-订阅模式‌(Publish/Subscribe)、‌模子-视图模式‌(Model/View)或‌源-监听器模式‌(Source/Listener)。‌
应用场景

观察者模式通常用于以了局景:

  • 变乱处理惩罚:观察者模式可以用于变乱处理惩罚体系,在体系中,变乱源对象可以将变乱关照全部的观察者对象,以便观察者对象可以实行相应的利用。
  • 状态监控:观察者模式可以用于监控对象的状态厘革,在状态改变时,关照全部观察者对象。
  • MVC模式:MVC模式中,视图与数据模子是分离的,视图通常是数据模子的观察者。当数据模子发生厘革时,关照全部的视图对象,更新视图。
  • 消息体系:观察者模式可以用于实现消息体系,在体系中,消息发布者可以将消息关照全部的观察者对象,以便观察者对象可以实行相应的利用。
  • GUI开发:观察者模式可以用于GUI开发,在GUI中,图形对象可以作为观察者,与数据模子对象创建关联,当数据模子发生厘革时,关照全部的观察者对象,更新界面。
 
优缺点

  观察者模式是一种活动型筹划模式,界说了一种一对多的依靠关系,当一个对象的状态发生改变时,它的全部依靠者都会收到关照并主动更新状态。
优点包罗:


  • 松耦合:观察者模式实现了对象之间的松耦合,被观察者和观察者之间的关系被解耦,它们都可以独立地厘革。
  • 对象的状态更新:观察者模式实现了对象的状态更新,当对象的状态发生厘革时,全部依靠它的对象都会收到关照并主动更新状态。
  • 拓展性:在观察者模式中,可以很方便地增长或删除观察者,实现拓展性。
缺点包罗:


  • 观察者模式大概导致变乱的洪泛,即被观察者的状态厘革导致大量的信息转达和处理惩罚,这大概低沉步调的性能。
  • 大概存在循环依靠题目:当观察者和被观察者之间存在相互依靠时,就会出现循环依靠的题目,这会导致体系的稳固性低沉。
  • 观察者模式须要思量开发服从和运行服从两个方面,开发服从较高,但须要思量怎样优化运行服从。
模式实现

委托方式实现
  1. using System;
  2. // 定义委托
  3. public delegate void NotifyEventHandler(string message);
  4. // 主题类
  5. public class Subject
  6. {
  7.     public event NotifyEventHandler NotifyEvent; // 声明事件
  8.     public void ChangeState()
  9.     {
  10.         Console.WriteLine("Subject: 我的状态改变了!");
  11.         NotifyEvent?.Invoke("状态已改变"); // 触发事件
  12.     }
  13. }
  14. // 观察者类
  15. public class Observer
  16. {
  17.     public void OnNotify(string message)
  18.     {
  19.         Console.WriteLine($"Observer: 收到通知 - {message}");
  20.     }
  21. }
  22. // 使用示例
  23. class Program
  24. {
  25.     static void Main()
  26.     {
  27.         Subject subject = new Subject();
  28.         Observer observer = new Observer();
  29.         // 订阅事件
  30.         subject.NotifyEvent += observer.OnNotify;
  31.         // 触发状态改变
  32.         subject.ChangeState();
  33.         // 取消订阅
  34.         subject.NotifyEvent -= observer.OnNotify;
  35.     }
  36. }
复制代码
接口方式实现
  1. using System;
  2. using System.Collections.Generic;
  3. // 观察者接口
  4. public interface IObserver
  5. {
  6.     void Update(string message);
  7. }
  8. // 主题接口
  9. public interface ISubject
  10. {
  11.     void Attach(IObserver observer);
  12.     void Detach(IObserver observer);
  13.     void Notify(string message);
  14. }
  15. // 具体主题类
  16. public class NewsSubject : ISubject
  17. {
  18.     private readonly List<IObserver> _observers = new List<IObserver>();
  19.     public void Attach(IObserver observer)
  20.     {
  21.         _observers.Add(observer);
  22.     }
  23.     public void Detach(IObserver observer)
  24.     {
  25.         _observers.Remove(observer);
  26.     }
  27.     public void Notify(string message)
  28.     {
  29.         foreach (var observer in _observers)
  30.         {
  31.             observer.Update(message);
  32.         }
  33.     }
  34. }
  35. // 具体观察者类
  36. public class UserObserver : IObserver
  37. {
  38.     private readonly string _userName;
  39.     public UserObserver(string name)
  40.     {
  41.         _userName = name;
  42.     }
  43.     public void Update(string message)
  44.     {
  45.         Console.WriteLine($"{_userName} 收到消息: {message}");
  46.     }
  47. }
  48. // 测试类
  49. public class Program
  50. {
  51.     public static void Main()
  52.     {
  53.         // 创建主题
  54.         ISubject news = new NewsSubject();
  55.         // 创建观察者
  56.         IObserver user1 = new UserObserver("张三");
  57.         IObserver user2 = new UserObserver("李四");
  58.         // 注册观察者
  59.         news.Attach(user1);
  60.         news.Attach(user2);
  61.         // 通知观察者
  62.         news.Notify("最新新闻:C#观察者模式实现成功!");
  63.         // 移除一个观察者
  64.         news.Detach(user1);
  65.         // 再次通知
  66.         news.Notify("更新新闻:张三已退订。");
  67.     }
  68. }
复制代码
 
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表