首页 > 编程语言 >c#-设计模式之观察者模式

c#-设计模式之观察者模式

时间:2024-11-03 17:57:56浏览次数:2  
标签:name c# void 观察者 stock 设计模式 public string

c#-设计模式之观察者模式

概念

指多个对象之间存在一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。该模式又称为包括发布-订阅(Publish/Subscribe)模式,该模式是行为型模式。

结构图

img

角色

  1. Subject(观察目标):观察目标是指被观察的对象,一般由抽象类或接口实现,观察目标把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,同时它定义了通知方法notify()。

  2. ConcreteSubject(具体观察目标):具体观察目标,实现观察目标,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。

  3. Observer(观察者):为所有具体观察者定义一个接口,观察者将对观察目标的改变做出反应。

  4. ConcreteObserver(具体观察者):实现观察目标所要求的接口,以便使自身状态与主题的状态相协调。

优点

  1. 降低了目标与观察者之间的耦合关系,观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,无须了解其具体观察者。由于观察目标和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。

  2. 观察者模式支持“广播通信”。主题会向所有的观察者发出通知。

  3. 观察者模式符合“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。

缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

  3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景

  1. 当一个对象的改变需要同时改变其它对象时,而且不必知道具体有多少对象要改变。

  2. 完成某件事情后,异步通知的场景,例如用户注册(发短信、电子邮件)、用户登录(发送IM消息)。

代码实现

  1. 当股票购买者所购买的股票价格发生变化的时候,系统将自动发送通知给购买该股票的所有股民。

    此场景中,股民为观察者,股票为被观察者。

    观察者接口

    public interface IObserver
    {
        void Update(Stock stock);
    }
    

    具体观察者:股民

    public class Investor : IObserver
    {
        private string name;
    
        public Investor(string name)
        {
            this.name = name;
        }
    
        public void Update(Stock stock)
        {
            Console.WriteLine($"通知股民{name}: {stock.GetSymbol()}股票的价格变更为{stock.GetPrice()}");
        }
    }
    

    主题接口

    public interface ISubject
    {
        void RegisterObserver(IObserver observer);
        void RemoveObserver(IObserver observer);
        void NotifyObservers();
    }
    

    具体的主题:股票

    public class Stock : ISubject
    {  
        private List<IObserver> observers;
        private string symbol;
        private double price;
    
        public Stock(string symbol, double price)
        {
            this.symbol = symbol;
            this.price = price;
            this.observers = new List<IObserver>();
        }
    
        public void RegisterObserver(IObserver observer)
        {
            observers.Add(observer);
        }
    
        public void RemoveObserver(IObserver observer)
        {
            observers.Remove(observer);
        }
    
        public void NotifyObservers()
        {
            foreach (var observer in observers)
            {
                observer.Update(this);
            }
        }
    
        public string GetSymbol()
        {
            return symbol;
        }
    
        public double GetPrice()
        {
            return price;
        }
    
        public void SetPrice(double price)
        {
            this.price = price;
            NotifyObservers();
        }
    }
    

    客户端

     static void Main(string[] args)
     {
         Stock stock = new Stock("A股", 120);
    
         Investor investor1 = new Investor("张三");
         Investor investor2 = new Investor("李四");
    
         stock.RegisterObserver(investor1);
         stock.RegisterObserver(investor2);
    
         stock.SetPrice(125);
         stock.SetPrice(115);
    
         stock.RemoveObserver(investor1);
    
         stock.SetPrice(130.0);
    
         Console.ReadLine();
     }
    

    运行截图

image

  1. 猫进屋了,老鼠都走了。

    此场景中,老鼠为观察者,猫为被观察者。

    public class Cat
    {
        private string color;
        private string name;
    
        public Cat(string color,string name)
        {
            this.color = color;
            this.name = name;
        }
    
        /// <summary>
        /// 定义事件
        /// </summary>
        public event Action CatCome;
    
        public void CatComing()
        {
            Console.WriteLine(color + "的猫:" + name + "进屋了。");
    
            if(CatCome!=null)
            {
                CatCome();
            }
        }
    }
    

​ 老鼠

public class Mouse
{
    private string color;
    private string name;

    public Mouse(string color, string name,Cat cat)
    {
        this.color = color;
        this.name = name;
        cat.CatCome += this.Run;
    }

    public void Run()
    {
        Console.WriteLine(color + "的" + name + "说猫来了,赶紧跑!!!");
    }
}

客户端

static void Main(string[] args)
{
    Cat cat1 = new Cat("黄色", "加菲");
    Mouse mouse1 = new Mouse("黑色", "米奇", cat1);
    Mouse mouse2 = new Mouse("黑色", "杰克", cat1);
    Mouse mouse3 = new Mouse("黑色", "杰瑞", cat1);
    cat1.CatComing();
}

运行截图
image

标签:name,c#,void,观察者,stock,设计模式,public,string
From: https://www.cnblogs.com/mingcore/p/18523711

相关文章

  • 最新毕设-SpringBoot-作业管理系统-42854(免费领项目)可做计算机毕业设计JAVA、PHP、爬
    springboot作业管理系统摘  要在信息化社会中,人们需要针对性的信息获取途径。然而,由于不同角度和偏好的存在,人们经常只能获得特定类型的信息,这也是技术攻克难题之一。为了解决作业管理系统等问题,本研究通过分析和研究,设计开发了作业管理系统。作业管理系统主要功能模块包......
  • JavaScript的迭代器和生成器
    1.迭代器Iterator1. 基本概念JavaScript表示集合的对象大致有Object,Array,Map,Set四种,并且这四种类型的数据之间可以相互以成员嵌套(如Array的成员可以是Object,而Map又可以嵌入Object的成员中),为了处理所有不同的数据结构,就需要统一的接口机制。迭代器(Iterator)就是这样一种......
  • c++模块(附加5篇笔记,看完点个赞)
    C++ 模板模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 ve......
  • 【最新原创毕设】基于SSM的体育赛事管理系统+74454(免费领源码)可做计算机毕业设计JAVA
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2平台分析2.1可行性分析2.1.1技术可行性2.1.2经济可行性2.1.3操作可行性2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析2.3 系统用例分析2.4业务流程分析2.5本章小......
  • 代码随想录算法训练营第十一天|leetcode150. 逆波兰表达式求值、leetcode239. 滑动窗
    1leetcode150.逆波兰表达式求值题目链接:150.逆波兰表达式求值-力扣(LeetCode)文章链接:代码随想录视频链接:栈的最后表演!|LeetCode:150.逆波兰表达式求值哔哩哔哩bilibili自己的思路:这是一道有思路,但是思路并不多的题目,就是我会觉得是先将数据进行添加,然后对于符号通过......
  • 代码随想录算法训练营第十五天|leetcode110. 平衡二叉树、leetcode257.二叉树的所有路
    1leetcode110.平衡二叉树题目链接:110.平衡二叉树-力扣(LeetCode)文章链接:代码随想录视频链接:后序遍历求高度,高度判断是否平衡|LeetCode:110.平衡二叉树_哔哩哔哩_bilibili1.1视频看后的思路1.1.1完整的代码就是不断判断,对其数据存储,其实突然发现每道题思路真的都很像,就......
  • 以客户为导向在开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序内容创作中的实践与
    摘要:本文深入探讨了在开源AI智能名片2+1链动模式S2B2C商城小程序相关内容创作中以客户为导向的方法和意义。阐述了如何在创作过程中通过与客户对话和转换客户视角来优化内容,以提升该小程序在市场中的竞争力和用户接受度。一、引言在数字化商业生态迅速发展的当下,开......
  • 开源AI智能名片2+1链动模式S2B2C商城小程序领域的未来探索
    摘要:随着技术的不断进步和市场的日益成熟,开源AI智能名片2+1链动模式S2B2C商城小程序领域展现出巨大的发展潜力。本文旨在探讨该领域未来值得深入研究的方向,包括技术创新、用户体验优化以及营销策略创新等方面,以期为企业和用户带来更多的价值和惊喜。一、引言在数字化时代,开......
  • LeetCode 19. 删除链表的倒数第 N 个结点(java)
    目录题目描述:代码:第一种:第二种:题目描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=[1],n=1输出:[]示例3:输入:head=[1,2],n=1输出:[1]代码:第一种:......
  • C++的0.3问题
    在计算机中,我们都知道0.1+0.2是不等于0.3的那等于多少呢?我们使用程序测试一下#include<iomanip>intmain(){std::cout<<std::setprecision(18)<<0.1+0.2;return0;}//out:0.30000000000000004还有一个专门以此当域名的网站FloatingPointMath在十进制系统中,10的质......