C# IObservable与IObserver观察者模式
C#中提供了IObservable<T>接口和IObserver<T>接口来实现观察者模式,IObservable<T>相当于Subject(主题)接口,下面我们就以代吗来说明下如何利用.net框架提供的观察者模式接口。
WeatherData类包含气温,湿度,气压等属性。
- class WeatherData
- {
- /// <summary>
- /// 气温
- /// </summary>
- public string temperature { get; set; }
- /// <summary>
- /// 湿度
- /// </summary>
- public string humility { get; set; }
- /// <summary>
- /// 气压
- /// </summary>
- public string pressure { get; set; }
- }
WeatherDataPublisher类实现了IObservable接口,实现了Subscribe订阅方法。
- class WeatherDataPublisher : IObservable<WeatherData>
- {
- List<IObserver<WeatherData>> observers = new List<IObserver<WeatherData>>();
- /// <summary>
- /// 订阅主题,将观察者添加到列表中
- /// </summary>
- /// <param name="observer"></param>
- /// <returns></returns>
- public IDisposable Subscribe(IObserver<WeatherData> observer)
- {
- observers.Add(observer);
- return new Unsubscribe(this.observers, observer);
- }
- /// <summary>
- /// 取消订阅类
- /// </summary>
- private class Unsubscribe : IDisposable
- {
- List<IObserver<WeatherData>> observers;
- IObserver<WeatherData> observer;
- public Unsubscribe(List<IObserver<WeatherData>> observers
- , IObserver<WeatherData> observer)
- {
- this.observer = observer;
- this.observers = observers;
- }
- public void Dispose()
- {
- if (this.observers != null)
- {
- this.observers.Remove(observer);
- }
- }
- }
- /// <summary>
- /// 通知已订阅的观察者
- /// </summary>
- /// <param name="weatherData"></param>
- private void Notify(WeatherData weatherData)
- {
- foreach (var observer in observers)
- {
- observer.OnNext(weatherData);
- }
- }
- /// <summary>
- /// 接收最新的天气数据
- /// </summary>
- /// <param name="weatherData"></param>
- public void ReciveNewData(WeatherData weatherData)
- {
- Notify(weatherData);
- }
- }
下面我们建立一个抽象类WeatherDisplayBase实现了IObserver接口,所有的天气展示板(观察者)继承这个抽象类,需实现OnNext方法,即接收到新数据推送后要进行的数据处理展示工作,并且可重写OnCompleted,OnError方法。
- abstract class WeatherDisplayBase : IObserver<WeatherData>
- {
- public virtual void OnCompleted()
- {
- }
- public virtual void OnError(Exception error)
- {
- }
- public abstract void OnNext(WeatherData value);
- }
CurrentConditionDisplay类为当前天气状况展示板,继承WeatherDisplayBase抽象类,展示最新的天气数据。
- class CurrentConditionDisplay : WeatherDisplayBase
- {
- public override void OnNext(WeatherData value)
- {
- Console.WriteLine("------------------");
- Console.WriteLine("当前天气状况板");
- Console.WriteLine(string.Format("温度:{0}\n湿度:{1}\n气压:{2}",
- value.temperature, value.humility, value.pressure));
- }
- }
StatisticsConditionDisplay类为气温统计展示板,继承WeatherDisplayBase抽象类,展示历史最高温度,最低温度,平均温度。
- class StatisticsConditionDisplay : WeatherDisplayBase
- {
- List<float> temperatures = new List<float>();
- public override void OnNext(WeatherData value)
- {
- float temperature;
- if (float.TryParse(value.temperature, out temperature))
- {
- temperatures.Add(temperature);
- }
- Console.WriteLine("------------------");
- Console.WriteLine("温度统计板");
- Console.WriteLine(string.Format("平均温度:{0}\n最高温度:{1}\n最低温度:{2}",
- temperatures.Average(), temperatures.Max(), temperatures.Min()));
- }
- }
使用方法
- class Program
- {
- static void Main(string[] args)
- {
- WeatherDataPublisher publisher = new WeatherDataPublisher();
- CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay();
- StatisticsConditionDisplay statisticsDisplay
- = new StatisticsConditionDisplay();
- //订阅当前天气展示板
- IDisposable currentDisplayUnsubscriber=
- publisher.Subscribe(currentDisplay);
- //订阅气温统计展示板
- IDisposable statisticsDisplayUnsubscriber =
- publisher.Subscribe(statisticsDisplay);
- for (int i = ; ; i++)
- {
- WeatherData weatherData = new WeatherData();
- Console.WriteLine("请输入温度,湿度,压力");
- string input = Console.ReadLine();
- var array= input.Split(',');
- weatherData.temperature = array[];
- weatherData.humility = array[];
- weatherData.pressure = array[];
- Console.WriteLine("");
- //将输入的新的天气数据传给天气数据发布器
- publisher.ReciveNewData(weatherData);
- Console.WriteLine("=============================");
- }
- }
- }
C# IObservable与IObserver观察者模式的更多相关文章
- 解构C#游戏框架uFrame兼谈游戏架构设计
1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...
- C#游戏框架uFrame
C#游戏框架uFrame兼谈游戏架构设计 c#语言规范 阅读目录 1.概览 2.基本概念 3.依赖注入 4.Manager of Managers 5.利用UniRX实现响应式编程 6.研究总结 回到 ...
- .NET Core/.NET之Stream简介 Rx.NET 简介
.NET Core/.NET之Stream简介 之前写了一篇C#装饰模式的文章提到了.NET Core的Stream, 所以这里尽量把Stream介绍全点. (都是书上的内容) .NET Core ...
- 诊断日志知多少 | DiagnosticSource 在.NET上的应用
1. 引言 最近为了解决ABP集成CAP时无法通过拦截器启用工作单元的问题,从小伙伴那里学了一招.借助DiagnossticSource,可以最小改动完成需求.关于DiagnosticSource晓东 ...
- Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1
Paip.Php Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1 异步调用的实现以及角色(:调用者 提货单) F ...
- 重温Observer模式--热水器·改
引言 在 C#中的委托和事件 一文的后半部分,讲述了Observer(观察者)模式,并使用委托和事件实现了这个模式.实际上,不使用委托和事件,一样可以实现Observer模式.在本文中,我将使用GOF ...
- C# 通知机制 IObserver<T> 和 IObservable<T>
class Program { public static void Main() { // Define a provider and two observers. LocationTracker ...
- 三种观察者模式的C#实现
系列主题:基于消息的软件架构模型演变 说起观察者模式,估计在园子里能搜出一堆来.所以写这篇博客的目的有两点: 观察者模式是写松耦合代码的必备模式,重要性不言而喻,抛开代码层面,许多组件都采用了Publ ...
- 设计模式学习之“观察者模式” [C#]
<深入浅出设计模式>学习笔记第二章 需求: 开发一套气象监测应用,如图: 气象站,目前有三种装置,温度.湿度和气压感应装置. WeatherData对象追踪气象站的数据,并更新到布告板,布 ...
随机推荐
- Asp.NetCore3.1 WebApi 使用Jwt 授权认证使用
1:导入NuGet包 Microsoft.AspNetCore.Authentication.JwtBearer 2:配置 jwt相关信息 3:在 startUp中 public void Confi ...
- Springboot(二)springboot之jsp支持
参考恒宇少年的博客:https://www.jianshu.com/p/90a84c814d0c springboot内部对jsp的支持并不是特别理想,而springboot推荐的视图是Thymele ...
- Day02_IP地址详解&进制转换&DOS基本命令与批处理
学于千峰教育开源课程 感谢 千峰教育官网 b站在线视频 IP地址详解 一.简单局域网的构成 局域网:一般称为内网 简单局域网的构成:交换机.网线.PC(其他IT终端) 交换机:用来组建内网的局域网的设 ...
- PHP array_fill_keys() 函数
------------恢复内容开始------------ 实例 用给定的指定键名的键值填充数组: <?php$keys=array("a","b",& ...
- PHP strrev() 函数
实例 反转字符串 "Hello World!": <?php高佣联盟 www.cgewang.comecho strrev("Hello World!") ...
- loj #6039 「雅礼集训 2017 Day5」珠宝 分组背包 决策单调性优化
LINK:珠宝 去年在某个oj上写过这道题 当时懵懂无知wa的不省人事 终于发现这个东西原来是有决策单调性的. 可以发现是一个01背包 但是过不了 冷静分析 01背包的复杂度有下界 如果过不了说明必然 ...
- MVC + EFCore 项目实战 - 数仓管理系统9 - 数据源管理完结篇
我们完成数据源管理的剩余部分:点击表名,预览表中数据. 我们需要完成的是下图的方框部分. 考虑到这块以后可能复用,我们将她独立出来,做成 view component. 新建 view compone ...
- Kafka 错误信息 java.io.IOException: Can't resolve address: VM_0_15_centos:9092
kafka 安装完成之后 代码运行的时候,运行完成报这个错误 java.io.IOException: Can't resolve address: VM_0_15_centos:9092 解决办 ...
- java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用)
java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用) 这是我关于会话技术的第二篇文章,对 Cookie有不了解的兄弟可以点击下方的Cookie跳转 Cookie链 ...
- 【lhyaaa】最近公共祖先LCA——倍增!!!
高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...