找回密码
 立即注册
首页 业界区 安全 《C# .net软件设计模式-----观察者模式》

《C# .net软件设计模式-----观察者模式》

靳谷雪 2026-2-9 20:35:12
观察者模式(Observer Pattern)是一种‌软件设计模式‌,属于对象行为模式的一种。它定义了一种‌一对多的依赖关系‌,使得多个观察者对象可以同时监听某个主题对象(也称被观察者)。当主题对象的状态发生改变时,会自动通知所有注册的观察者,让它们能够自动更新自身状态。‌

这种模式的核心在于‌解耦‌:主题对象无需知道具体有哪些观察者,只需维护一个观察者列表并在状态变化时通知它们;而观察者也只需关注自己感兴趣的事件,无需主动轮询主题状态。‌

观察者模式在软件架构中被广泛应用,尤其适用于‌事件处理系统‌、‌用户界面与业务数据的同步‌、‌权限管理‌等场景。例如,在图形界面中,界面元素(观察者)可以监听后台数据模型(主题)的变化,一旦数据更新,界面自动刷新。‌

主要角色



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


推模式与拉模式

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


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

观察者模式通常用于以下场景:

  • 事件处理:观察者模式可以用于事件处理系统,在系统中,事件源对象可以将事件通知所有的观察者对象,以便观察者对象可以执行相应的操作。

  • 状态监控:观察者模式可以用于监控对象的状态变化,在状态改变时,通知所有观察者对象。

  • MVC模式:MVC模式中,视图与数据模型是分离的,视图通常是数据模型的观察者。当数据模型发生变化时,通知所有的视图对象,更新视图。

  • 消息系统:观察者模式可以用于实现消息系统,在系统中,消息发布者可以将消息通知所有的观察者对象,以便观察者对象可以执行相应的操作。

  • GUI开发:观察者模式可以用于GUI开发,在GUI中,图形对象可以作为观察者,与数据模型对象建立关联,当数据模型发生变化时,通知所有的观察者对象,更新界面。

 
优缺点

  观察者模式是一种行为型设计模式,定义了一种一对多的依赖关系,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新状态。
优点包括:


  • 松耦合:观察者模式实现了对象之间的松耦合,被观察者和观察者之间的关系被解耦,它们都可以独立地变化。

  • 对象的状态更新:观察者模式实现了对象的状态更新,当对象的状态发生变化时,所有依赖它的对象都会收到通知并自动更新状态。

  • 拓展性:在观察者模式中,可以很方便地增加或删除观察者,实现拓展性。

缺点包括:


  • 观察者模式可能导致事件的洪泛,即被观察者的状态变化导致大量的信息传递和处理,这可能降低程序的性能。

  • 可能存在循环依赖问题:当观察者和被观察者之间存在互相依赖时,就会出现循环依赖的问题,这会导致系统的稳定性降低。

  • 观察者模式需要考虑开发效率和运行效率两个方面,开发效率较高,但需要考虑如何优化运行效率。

模式实现

委托方式实现
  1. using System;  // 定义委托 public delegate void NotifyEventHandler(string message);  // 主题类 public class Subject {     public event NotifyEventHandler NotifyEvent; // 声明事件      public void ChangeState()     {         Console.WriteLine("Subject: 我的状态改变了!");         NotifyEvent?.Invoke("状态已改变"); // 触发事件     } }  // 观察者类 public class Observer {     public void OnNotify(string message)     {         Console.WriteLine($"Observer: 收到通知 - {message}");     } }  // 使用示例 class Program {     static void Main()     {         Subject subject = new Subject();         Observer observer = new Observer();          // 订阅事件         subject.NotifyEvent += observer.OnNotify;          // 触发状态改变         subject.ChangeState();          // 取消订阅         subject.NotifyEvent -= observer.OnNotify;     } }
复制代码
接口方式实现
  1. using System; using System.Collections.Generic;  // 观察者接口 public interface IObserver {     void Update(string message); }  // 主题接口 public interface ISubject {     void Attach(IObserver observer);     void Detach(IObserver observer);     void Notify(string message); }  // 具体主题类 public class NewsSubject : ISubject {     private readonly List _observers = new List();      public void Attach(IObserver observer)     {         _observers.Add(observer);     }      public void Detach(IObserver observer)     {         _observers.Remove(observer);     }      public void Notify(string message)     {         foreach (var observer in _observers)         {             observer.Update(message);         }     } }  // 具体观察者类 public class UserObserver : IObserver {     private readonly string _userName;      public UserObserver(string name)     {         _userName = name;     }      public void Update(string message)     {         Console.WriteLine($"{_userName} 收到消息: {message}");     } }  // 测试类 public class Program {     public static void Main()     {         // 创建主题         ISubject news = new NewsSubject();          // 创建观察者         IObserver user1 = new UserObserver("张三");         IObserver user2 = new UserObserver("李四");          // 注册观察者         news.Attach(user1);         news.Attach(user2);          // 通知观察者         news.Notify("最新新闻:C#观察者模式实现成功!");          // 移除一个观察者         news.Detach(user1);          // 再次通知         news.Notify("更新新闻:张三已退订。");     } }
复制代码
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

7 天前

举报

喜欢鼓捣这些软件,现在用得少,谢谢分享!
您需要登录后才可以回帖 登录 | 立即注册