c#面向对象23种设计模式——"观察者模式"

一、概述

观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当主题(被观察者)对象的状态发生变化时,其所有依赖(观察者)对象都会自动进行更新。

二、简介

观察者模式的原理包括以下几个要素:

  1. 主题(ISubject):主题对象负责管理观察者对象的注册、删除和通知操作。它维护一个观察者列表,并提供了用于添加、删除和通知观察者的方法。
  2. 观察者(IObserver):观察者对象对主题对象的状态变化进行观察,并作出相应的反应。观察者对象通常定义了一个接口或抽象类,其中包含了接收更新通知的方法。
  3. 具体主题(NewsPublisher):具体主题对象是主题的具体实现,它维护了一个当前状态,并在状态发生变化时通知所有注册的观察者对象。
  4. 具体观察者(Users):具体观察者对象是观察者的具体实现,它实现了接收更新通知的方法,并定义了在接收到通知时具体进行的操作。

具体实现观察者模式时,通常的做法是在主题对象中维护一个观察者列表,并提供方法用于添加、删除和通知观察者。当主题对象的状态发生变化时,它会遍历观察者列表,调用每个观察者对象的更新方法。观察者对象则根据接收到的更新信息进行相应的处理操作。

观察者模式的原理可以帮助实现松耦合的对象间通信,使得对象之间的依赖关系变得灵活可扩展。同时,观察者模式也可以支持多个观察者对象对同一主题进行观察,使得对象之间的关系更加松散,提高系统的可维护性和扩展性。

三、代码实现演示

1、新闻对象

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    /// <summary>
    /// 新闻
    /// </summary>
    public class News
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 内容
        /// </summary>
        public string Context { get; set; }
    }
}

2、主题接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    /// <summary>
    /// 主题
    /// </summary>
    public interface ISubject
    {
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="observer">观察者的行为</param>
        public void Regist(IObserver observer);
        /// <summary>
        /// 注销
        /// </summary>
        /// <param name="observer">观察者的行为</param>
        public void LogOut(IObserver observer);
        /// <summary>
        /// 通知
        /// </summary>
        /// <param name="news">新闻信息</param>
        public void Inform(News news);
    }
}

3、主题具体实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    /// <summary>
    /// 主题实现
    /// 继承主题接口
    /// </summary>
    public class NewsPublisher : ISubject
    {
        /// <summary>
        /// 继承了观察者操作的用户列表
        /// </summary>
        private List<IObserver> Observers = new List<IObserver>();

        /// <summary>
        /// 注销接口实现
        /// 删除观察者的行为
        /// </summary>
        /// <param name="observer">用户</param>
        public void LogOut(IObserver observer)
        {
            Observers.Remove(observer);
            Console.WriteLine("注销");
            Console.WriteLine();
        }

        /// <summary>
        /// 注册接口实现
        /// 添加观察者的行为
        /// </summary>
        /// <param name="observer">用户</param>
        public void Regist(IObserver observer)
        {
            Observers.Add(observer);
            Console.WriteLine("注册");
            Console.WriteLine();
        }

        /// <summary>
        /// 通知接口实现
        /// 遍历所有用户通知行为
        /// </summary>
        /// <param name="news">新闻信息</param>
        public void Inform(News news)
        {
            foreach (IObserver observer in Observers)
            {
                observer.Observer(news);
            }
            Console.WriteLine("通知");
            Console.WriteLine();
        }
    }
}

4、观察者行为接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    /// <summary>
    /// 观察者行为接口
    /// </summary>
    public interface IObserver
    {
        /// <summary>
        /// 行为操作
        /// </summary>
        /// <param name="news">新闻信息</param>
        public void Observer(News news);
    }
}

5、观察者具体实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    /// <summary>
    /// 观察者,继承观察者的行为
    /// </summary>
    public class Users : IObserver
    {
        /// <summary>
        /// 实现行为
        /// </summary>
        /// <param name="news"></param>
        public void Observer(News news)
        {
            Console.WriteLine($"订阅新闻=> 标题:{news.Title},描述:{news.Context}");
        }
    }
}

四、效果演示

1、代码调用

  static void Main(string[] args)
  {
      //定义一个主题
      NewsPublisher newsPublisher = new NewsPublisher();

      //定义一个用户
      Users users = new Users();

      //把用户通过注册接口添加到主题中的用户列表
      newsPublisher.Regist(users);

      //定义一个新闻
      News news = new News()
      {
          Title = "新闻",
          Context = "新闻描述"
      };
      //把新闻通过通知的接口 告诉用户,让用户实现用户行为
      newsPublisher.Inform(news);

      //把用户通过注销接口删除主题中的用户列表中的用户
      newsPublisher.LogOut(users);


      newsPublisher.Inform(news);
  }

2、结果

image.png

以上就是我了解到行为型设计模式中的————"观察者模式"的简单示例,大家有更好的见解,欢迎到评论区讨论!!!

全部评论

相关推荐

07-02 10:44
门头沟学院 C++
码农索隆:太实诚了,告诉hr,你能实习至少6个月
点赞 评论 收藏
分享
深夜书店vv:腾讯是这样的,去年很多走廊都加桌子当工区
点赞 评论 收藏
分享
05-11 11:48
河南大学 Java
程序员牛肉:我是26届的双非。目前有两段实习经历,大三上去的美团,现在来字节了,做的是国际电商的营销业务。希望我的经历对你有用。 1.好好做你的CSDN,最好是直接转微信公众号。因为这本质上是一个很好的展示自己技术热情的证据。我当时也是烂大街项目(网盘+鱼皮的一个项目)+零实习去面试美团,但是当时我的CSDN阅读量超百万,微信公众号阅读量40万。面试的时候面试官就告诉我说觉得我对技术挺有激情的。可以看看我主页的美团面试面经。 因此花点时间好好做这个知识分享,最好是单拉出来搞一个板块。各大公司都极其看中知识落地的能力。 可以看看我的简历对于博客的描述。这个帖子里面有:https://www.nowcoder.com/discuss/745348200596324352?sourceSSR=users 2.实习经历有一些东西删除了,目前看来你的产出其实很少。有些内容其实很扯淡,最好不要保留。有一些点你可能觉得很牛逼,但是面试官眼里是减分的。 你还能负责数据库表的设计?这个公司得垃圾成啥样子,才能让一个实习生介入数据库表的设计,不要写这种东西。 一个公司的财务审批系统应该是很稳定的吧?为什么你去了才有RBAC权限设计?那这个公司之前是怎么处理权限分离的?这些东西看着都有点扯淡了。 还有就是使用Redis实现轻量级的消息队列?那为什么这一块不使用专业的MQ呢?为什么要使用redis,这些一定要清楚, 就目前看来,其实你的这个实习技术还不错。不要太焦虑。就是有一些内容有点虚了。可以考虑从PR中再投一点产出
投递美团等公司9个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务