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("=============================");
}
}
}

最新文章

  1. switch 方法 计算器
  2. Property ClientHeight does not exist 问题解决
  3. AS2.0大步更新 Google强势逆天
  4. ylbtech-dbs:ylbtech-6,record(生活记录)
  5. Telnet、FTP、SSH、SFTP、SCP
  6. struts2 权限拦截器 拦截没有登陆的请求
  7. 控制器 - URL routing HTTP module(一)
  8. jQuery easyui刷新当前tabs
  9. 用Redis作为Mysql数据库的缓存
  10. SVN常见问题
  11. codeforces 893A Chess For Three 模拟
  12. [2]十道算法题【Java实现】
  13. PAT1086:Tree Traversals Again
  14. django——FBV与CBV
  15. WinForm界面设计优化过程
  16. windows蜜汁调音
  17. Nginx 多域名配置
  18. grep搜索文本
  19. git 使用 添加分支
  20. ardunio 实现RS485通讯-下位机

热门文章

  1. 支持向量机SMO算法实现(注释详细)
  2. 大数据篇:一文读懂@数据仓库(PPT文字版)
  3. 台账建立和sqlite数据库的数据导入和导入问题
  4. 设备管理的数据库路径是/storage/sdcard0/data/devuce-db
  5. flask中url_for使用endpoint和视图函数名
  6. PHP操作Redis步骤详解
  7. MySQL索引介绍和实战
  8. 从包含10个无符号数的字节数组array中选出最小的一个数存于变量MIN中,并将该数以十进制形式显示出来。
  9. Python os.tmpnam() 方法
  10. luogu P4515 [COCI2009-2010#6] XOR 容斥