设计模式(十五)之观察者模式

简介: 观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了上述具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标,另一类是观察该目标的观察者们。正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。

QQ图片20220424162536.jpg

观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了上述具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标,另一类是观察该目标的观察者们。


正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。


当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。


模式中具有的角色


抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。


具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。


抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。


具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。


观察者模式类图:


QQ图片20220424162539.png


举个例子:


Csdn博客就是一个观察者模式,比如你关注一些作者的博客,当作者有博客发布时候,你就会收到一条该作者发布的博客的消息。


抽象主题:Blog 博客


具体主题:MyBlog   的博客


抽象观察者:IObserver


具体的观察者:Observer


上代码:


首先我们需要定义一个博客的抽象类,其中有订阅功能


Blog.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Observer
{
    /// <summary>
    /// 博客抽象类,有订阅功能
    /// </summary>
    public abstract class blog
    {
        /// <summary>
        /// 订阅者列表
        /// </summary>
        public List<IObserver> observerList = new List<IObserver>();
        /// <summary>
        /// 博客标题
        /// </summary>
        public string blogTitle = "";
        /// <summary>
        /// 博客作者
        /// </summary>
        public string blogAuthor = "";
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="title">博客标题</param>
        /// <param name="author">博客作者</param>
        public blog(string title,string author)
        {
            this.blogAuthor = author;
            this.blogTitle = title;
        }
        /// <summary>
        /// 添加订阅者
        /// </summary>
        /// <param name="name">订阅者对象</param>
        public void AddObserver(IObserver name)
        {
            // 如果其没有订阅,添加
            if (!observerList.Contains(name))
            {
                observerList.Add(name);
            }
        }
        /// <summary>
        /// 删除订阅者
        /// </summary>
        /// <param name="name">订阅者对象</param>
        public void DelObserver(IObserver name)
        {
            // 如果其没有订阅,添加
            if (!observerList.Contains(name))
            {
                observerList.Remove(name);
            }
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        public void SendMessage()
        {
            for (int i = 0; i < observerList.Count; i++)
            {
                observerList[i].AcceptMessage(this);
            }
        }
    }
}


接下来我们需要一个观察者的接口:


IObserver.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Observer
{
    /// <summary>
    /// 订阅者接口
    /// </summary>
    public interface IObserver
    {
        void AcceptMessage(blog blogs);
    }
}


具体的博客


MyBlog.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Observer
{
    public class MyBlog : blog
    {
        public MyBlog(string title,string author) : base(title,author)
        {
        }
    }
}


具体的观察者:


Observer.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Observer
{
    public class Observer:IObserver
    {
        /// <summary>
        /// 订阅者名字
        /// </summary>
        public string observerName = "";
        public Observer(string name)
        {
            this.observerName = name;
        }
        /// <summary>
        /// 接受博客通知方法
        /// </summary>
        /// <param name="blogs"></param>
        public void AcceptMessage(blog blogs)
        {
            Console.WriteLine("订阅者"+observerName+"收到了"+blogs.blogAuthor+"发布的"+blogs.blogTitle+"的通知");
        }
    }
}


客户端调用:


ProGram.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Observer
{
    class Program
    {
        static void Main(string[] args)
        {
            // 初始化三个订阅者
            Observer aaa = new Observer("张三");
            Observer bbb = new Observer("李四");
            Observer ccc = new Observer("王五");
            // 初始化一个博客
            MyBlog gc = new MyBlog("观察者模式","camellia");
            // 将三个订阅者添加到该博客
            gc.AddObserver(aaa);
            gc.AddObserver(bbb);
            gc.AddObserver(ccc);
            // 发送博客通知
            gc.SendMessage();
            Console.ReadKey();
        }
    }
}


最终效果如下:


QQ图片20220424162541.jpg


观察者模式主要应用于一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者。当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式。


以上就是观察者的大概实现过程。


C#中对于观察者模式还有使用委托来实现的例子。与上边的区别就是将订阅者接口使用委托来代替。其余都相同,这里不做展示,又兴趣可以尝试下。



目录
相关文章
|
4月前
|
设计模式 监控 安全
设计模式 | 观察者模式
设计模式 | 观察者模式
23 0
|
4月前
|
设计模式 前端开发 数据中心
设计模式之观察者模式
设计模式之观察者模式
|
5月前
|
设计模式 存储 Java
认真学习设计模式之观察者模式(Observer Pattern)
认真学习设计模式之观察者模式(Observer Pattern)
33 0
|
3月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
1月前
|
设计模式 监控 Java
设计模式 - 观察者模式(Observer):Java中的战术与策略
【4月更文挑战第7天】观察者模式是构建可维护、可扩展系统的关键,它在Java中通过`Observable`和`Observer`实现对象间一对多的依赖关系,常用于事件处理、数据绑定和同步。该模式支持事件驱动架构、数据同步和实时系统,但需注意避免循环依赖、控制通知粒度,并关注性能和内存泄漏问题。通过明确角色、使用抽象和管理观察者注册,可最大化其效果。
|
2月前
|
设计模式 存储 Java
【设计模式】观察者模式
【设计模式】观察者模式
|
17天前
|
设计模式 消息中间件 存储
【设计模式系列笔记】观察者模式
观察者模式是一种设计模式,它允许一个对象(主题)维护一组依赖于它的对象(观察者)并在状态发生变化时通知它们。这种模式属于行为型模式。在观察者模式中,主题是被观察的对象,而观察者是依赖于主题的对象,当主题的状态发生变化时,所有注册的观察者都会得到通知并自动更新。
23 0
|
5月前
|
设计模式 存储 Java
Java设计模式【二十】:观察者模式
Java设计模式【二十】:观察者模式
27 0
|
1月前
|
设计模式 Java
23种设计模式,观察者模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
24 2
|
2月前
|
设计模式 前端开发
观察者模式--设计模式
观察者模式--设计模式
11 0