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对象追踪气象站的数据,并更新到布告板,布 ...
随机推荐
- JS闭包应用场景之函数回调(含函数的调用个人理解)
首先我们来绑定一个函数给click事件,这个很好理解,就是创建一个匿名函数作为回调绑定给click事件,如下: 但如果我们想声明一个函数作为回调来绑定多个元素呢,例如下面(注意:绑定事件后不用加括号, ...
- WinForm微信扫码登录
源码还需优化,不喜勿喷. 微信官方文档 : https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat ...
- spring tx——@EnableTransactionManagement
@EnableTransactionManagement import了TransactionManagementConfigurationSelector,而TransactionManagemen ...
- 今天成功完成二维码扫描程序, 利用zxing
利用的网上参考文档是https://blog.csdn.net/gorky_19/article/details/78454030,里面介绍了如何修改build.gradle的dependency 和 ...
- 数据库事务的四个特性ACID
原子性[Atomicity] 原子性指的指的就是这个操作,要么全部成功,要么全部失败回滚.不存在其他的情况. 一致性(Consistency) 一致性是指事务必须使数据库从一个一致性状态变换到另一个一 ...
- Spring boot 基础整理(一)
环境准备 (1)JDK 环境必须是 1.8 及以上(2)后面要使用到 Maven 管理工具 3.2.5 及以上版本,所以会先介绍 Maven 的安装与配置(3)开发工具建议使用 IDEA,也可以 My ...
- HTML 统一资源定位器(Uniform Resource Locators)
HTML 统一资源定位器(Uniform Resource Locators) URL 是一个网页地址.高佣联盟 www.cgewang.com URL可以由字母组成,如"runoob.co ...
- 4.26 省选模拟赛 T3 状压dp 差分求答案
LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...
- Netty(一):server启动流程解析
netty作为一个被广泛应用的通信框架,有必要我们多了解一点. 实际上netty的几个重要的技术亮点: 1. reactor的线程模型; 2. 安全有效的nio非阻塞io模型应用; 3. pipeli ...
- 【BZOJ4631】踩气球 题解(线段树)
题目链接 ---------------------- 题目大意:给定一个长度为$n$的序列${a_i}$.现在有$m$个区间$[l_i,r_i]$和$q$个操作,每次选取一个$x$使得$a_x--$ ...