C# IObservable与IObserver观察者模式
2024-09-07 00:22:25
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("=============================");
}
}
}
最新文章
- switch 方法 计算器
- Property ClientHeight does not exist 问题解决
- AS2.0大步更新 Google强势逆天
- ylbtech-dbs:ylbtech-6,record(生活记录)
- Telnet、FTP、SSH、SFTP、SCP
- struts2 权限拦截器 拦截没有登陆的请求
- 控制器 - URL routing HTTP module(一)
- jQuery easyui刷新当前tabs
- 用Redis作为Mysql数据库的缓存
- SVN常见问题
- codeforces 893A	Chess For Three 模拟
- [2]十道算法题【Java实现】
- PAT1086:Tree Traversals Again
- django——FBV与CBV
- WinForm界面设计优化过程
- windows蜜汁调音
- Nginx 多域名配置
- grep搜索文本
- git 使用 添加分支
- ardunio 实现RS485通讯-下位机
热门文章
- 支持向量机SMO算法实现(注释详细)
- 大数据篇:一文读懂@数据仓库(PPT文字版)
- 台账建立和sqlite数据库的数据导入和导入问题
- 设备管理的数据库路径是/storage/sdcard0/data/devuce-db
- flask中url_for使用endpoint和视图函数名
- PHP操作Redis步骤详解
- MySQL索引介绍和实战
- 从包含10个无符号数的字节数组array中选出最小的一个数存于变量MIN中,并将该数以十进制形式显示出来。
- Python os.tmpnam() 方法
- luogu P4515 [COCI2009-2010#6] XOR 容斥