C#中提供了IObservable<T>接口和IObserver<T>接口来实现观察者模式,IObservable<T>相当于Subject(主题)接口,下面我们就以代吗来说明下如何利用.net框架提供的观察者模式接口。

WeatherData类包含气温,湿度,气压等属性。

  1. class WeatherData
  2. {
  3. /// <summary>
  4. /// 气温
  5. /// </summary>
  6. public string temperature { get; set; }
  7. /// <summary>
  8. /// 湿度
  9. /// </summary>
  10. public string humility { get; set; }
  11. /// <summary>
  12. /// 气压
  13. /// </summary>
  14. public string pressure { get; set; }
  15. }

WeatherDataPublisher类实现了IObservable接口,实现了Subscribe订阅方法。

  1. class WeatherDataPublisher : IObservable<WeatherData>
  2. {
  3. List<IObserver<WeatherData>> observers = new List<IObserver<WeatherData>>();
  4. /// <summary>
  5. /// 订阅主题,将观察者添加到列表中
  6. /// </summary>
  7. /// <param name="observer"></param>
  8. /// <returns></returns>
  9. public IDisposable Subscribe(IObserver<WeatherData> observer)
  10. {
  11. observers.Add(observer);
  12. return new Unsubscribe(this.observers, observer);
  13. }
  14. /// <summary>
  15. /// 取消订阅类
  16. /// </summary>
  17. private class Unsubscribe : IDisposable
  18. {
  19. List<IObserver<WeatherData>> observers;
  20. IObserver<WeatherData> observer;
  21. public Unsubscribe(List<IObserver<WeatherData>> observers
  22. , IObserver<WeatherData> observer)
  23. {
  24. this.observer = observer;
  25. this.observers = observers;
  26. }
  27.  
  28. public void Dispose()
  29. {
  30. if (this.observers != null)
  31. {
  32. this.observers.Remove(observer);
  33. }
  34. }
  35. }
  36. /// <summary>
  37. /// 通知已订阅的观察者
  38. /// </summary>
  39. /// <param name="weatherData"></param>
  40. private void Notify(WeatherData weatherData)
  41. {
  42. foreach (var observer in observers)
  43. {
  44. observer.OnNext(weatherData);
  45. }
  46. }
  47. /// <summary>
  48. /// 接收最新的天气数据
  49. /// </summary>
  50. /// <param name="weatherData"></param>
  51. public void ReciveNewData(WeatherData weatherData)
  52. {
  53. Notify(weatherData);
  54. }
  55. }

下面我们建立一个抽象类WeatherDisplayBase实现了IObserver接口,所有的天气展示板(观察者)继承这个抽象类,需实现OnNext方法,即接收到新数据推送后要进行的数据处理展示工作,并且可重写OnCompleted,OnError方法。

  1. abstract class WeatherDisplayBase : IObserver<WeatherData>
  2. {
  3. public virtual void OnCompleted()
  4. {
  5. }
  6. public virtual void OnError(Exception error)
  7. {
  8. }
  9. public abstract void OnNext(WeatherData value);
  10. }

CurrentConditionDisplay类为当前天气状况展示板,继承WeatherDisplayBase抽象类,展示最新的天气数据。

  1. class CurrentConditionDisplay : WeatherDisplayBase
  2. {
  3. public override void OnNext(WeatherData value)
  4. {
  5. Console.WriteLine("------------------");
  6. Console.WriteLine("当前天气状况板");
  7. Console.WriteLine(string.Format("温度:{0}\n湿度:{1}\n气压:{2}",
  8. value.temperature, value.humility, value.pressure));
  9. }
  10. }

StatisticsConditionDisplay类为气温统计展示板,继承WeatherDisplayBase抽象类,展示历史最高温度,最低温度,平均温度。

  1. class StatisticsConditionDisplay : WeatherDisplayBase
  2. {
  3. List<float> temperatures = new List<float>();
  4. public override void OnNext(WeatherData value)
  5. {
  6. float temperature;
  7. if (float.TryParse(value.temperature, out temperature))
  8. {
  9. temperatures.Add(temperature);
  10. }
  11. Console.WriteLine("------------------");
  12. Console.WriteLine("温度统计板");
  13. Console.WriteLine(string.Format("平均温度:{0}\n最高温度:{1}\n最低温度:{2}",
  14. temperatures.Average(), temperatures.Max(), temperatures.Min()));
  15. }
  16. }

使用方法

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. WeatherDataPublisher publisher = new WeatherDataPublisher();
  6. CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay();
  7. StatisticsConditionDisplay statisticsDisplay
  8. = new StatisticsConditionDisplay();
  9. //订阅当前天气展示板
  10. IDisposable currentDisplayUnsubscriber=
  11. publisher.Subscribe(currentDisplay);
  12. //订阅气温统计展示板
  13. IDisposable statisticsDisplayUnsubscriber =
  14. publisher.Subscribe(statisticsDisplay);
  15.  
  16. for (int i = ; ; i++)
  17. {
  18. WeatherData weatherData = new WeatherData();
  19. Console.WriteLine("请输入温度,湿度,压力");
  20. string input = Console.ReadLine();
  21. var array= input.Split(',');
  22. weatherData.temperature = array[];
  23. weatherData.humility = array[];
  24. weatherData.pressure = array[];
  25. Console.WriteLine("");
  26. //将输入的新的天气数据传给天气数据发布器
  27. publisher.ReciveNewData(weatherData);
  28. Console.WriteLine("=============================");
  29. }
  30. }
  31. }

C# IObservable与IObserver观察者模式的更多相关文章

  1. 解构C#游戏框架uFrame兼谈游戏架构设计

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

  2. C#游戏框架uFrame

    C#游戏框架uFrame兼谈游戏架构设计 c#语言规范 阅读目录 1.概览 2.基本概念 3.依赖注入 4.Manager of Managers 5.利用UniRX实现响应式编程 6.研究总结 回到 ...

  3. .NET Core/.NET之Stream简介 Rx.NET 简介

    .NET Core/.NET之Stream简介   之前写了一篇C#装饰模式的文章提到了.NET Core的Stream, 所以这里尽量把Stream介绍全点. (都是书上的内容) .NET Core ...

  4. 诊断日志知多少 | DiagnosticSource 在.NET上的应用

    1. 引言 最近为了解决ABP集成CAP时无法通过拦截器启用工作单元的问题,从小伙伴那里学了一招.借助DiagnossticSource,可以最小改动完成需求.关于DiagnosticSource晓东 ...

  5. Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1

    Paip.Php  Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1       异步调用的实现以及角色(:调用者 提货单) F ...

  6. 重温Observer模式--热水器·改

    引言 在 C#中的委托和事件 一文的后半部分,讲述了Observer(观察者)模式,并使用委托和事件实现了这个模式.实际上,不使用委托和事件,一样可以实现Observer模式.在本文中,我将使用GOF ...

  7. C# 通知机制 IObserver<T> 和 IObservable<T>

    class Program { public static void Main() { // Define a provider and two observers. LocationTracker ...

  8. 三种观察者模式的C#实现

    系列主题:基于消息的软件架构模型演变 说起观察者模式,估计在园子里能搜出一堆来.所以写这篇博客的目的有两点: 观察者模式是写松耦合代码的必备模式,重要性不言而喻,抛开代码层面,许多组件都采用了Publ ...

  9. 设计模式学习之“观察者模式” [C#]

    <深入浅出设计模式>学习笔记第二章 需求: 开发一套气象监测应用,如图: 气象站,目前有三种装置,温度.湿度和气压感应装置. WeatherData对象追踪气象站的数据,并更新到布告板,布 ...

随机推荐

  1. Asp.NetCore3.1 WebApi 使用Jwt 授权认证使用

    1:导入NuGet包 Microsoft.AspNetCore.Authentication.JwtBearer 2:配置 jwt相关信息 3:在 startUp中 public void Confi ...

  2. Springboot(二)springboot之jsp支持

    参考恒宇少年的博客:https://www.jianshu.com/p/90a84c814d0c springboot内部对jsp的支持并不是特别理想,而springboot推荐的视图是Thymele ...

  3. Day02_IP地址详解&进制转换&DOS基本命令与批处理

    学于千峰教育开源课程 感谢 千峰教育官网 b站在线视频 IP地址详解 一.简单局域网的构成 局域网:一般称为内网 简单局域网的构成:交换机.网线.PC(其他IT终端) 交换机:用来组建内网的局域网的设 ...

  4. PHP array_fill_keys() 函数

    ------------恢复内容开始------------ 实例 用给定的指定键名的键值填充数组: <?php$keys=array("a","b",& ...

  5. PHP strrev() 函数

    实例 反转字符串 "Hello World!": <?php高佣联盟 www.cgewang.comecho strrev("Hello World!") ...

  6. loj #6039 「雅礼集训 2017 Day5」珠宝 分组背包 决策单调性优化

    LINK:珠宝 去年在某个oj上写过这道题 当时懵懂无知wa的不省人事 终于发现这个东西原来是有决策单调性的. 可以发现是一个01背包 但是过不了 冷静分析 01背包的复杂度有下界 如果过不了说明必然 ...

  7. MVC + EFCore 项目实战 - 数仓管理系统9 - 数据源管理完结篇

    我们完成数据源管理的剩余部分:点击表名,预览表中数据. 我们需要完成的是下图的方框部分. 考虑到这块以后可能复用,我们将她独立出来,做成 view component. 新建 view compone ...

  8. 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 解决办 ...

  9. java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用)

    java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用) 这是我关于会话技术的第二篇文章,对 Cookie有不了解的兄弟可以点击下方的Cookie跳转 Cookie链 ...

  10. 【lhyaaa】最近公共祖先LCA——倍增!!!

    高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...