using System.Collections.Generic;
public static void Main()
WeatherDataHandler weatherData = new WeatherDataHandler();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
weatherData.SetMeasurements(80, 65, 30.4f);
weatherData.SetMeasurements(82, 70, 29.2f);
weatherData.SetMeasurements(78, 90, 29.2f);
public interface IDisplayElement {
public class WeatherDataHandler : IObservable<WeatherDataInfo> {
private List<IObserver<WeatherDataInfo>> observers;
private List<WeatherDataInfo> weatherData;
public WeatherDataHandler()
observers = new List<IObserver<WeatherDataInfo>>();
weatherData = new List<WeatherDataInfo>();
public IDisposable Subscribe(IObserver<WeatherDataInfo> observer)
if (! observers.Contains(observer)) {
foreach (var item in weatherData)
return new Unsubscriber<WeatherDataInfo>(observers, observer);
public void SetMeasurements(float temperature, float humidity, float pressure)
var info = new WeatherDataInfo(temperature, humidity, pressure);
foreach (var observer in observers)
internal class Unsubscriber<WeatherDataInfo> : IDisposable
private List<IObserver<WeatherDataInfo>> _observers;
private IObserver<WeatherDataInfo> _observer;
internal Unsubscriber(List<IObserver<WeatherDataInfo>> observers, IObserver<WeatherDataInfo> observer)
this._observers = observers;
this._observer = observer;
if (_observers.Contains(_observer))
_observers.Remove(_observer);
public class WeatherDataInfo {
private float temperature;
public float Temperature { get {return temperature;} }
public float Humidity { get {return humidity;} }
public float Pressure { get {return pressure;} }
public WeatherDataInfo(float temperature, float humidity, float pressure)
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
public class CurrentConditionsDisplay : IDisplayElement, IObserver<WeatherDataInfo>
private float temperature;
private IDisposable cancellation;
public CurrentConditionsDisplay(WeatherDataHandler provider)
cancellation = provider.Subscribe(this);
public virtual void OnNext(WeatherDataInfo value)
this.temperature = value.Temperature;
this.humidity = value.Humidity;
public virtual void OnError(Exception e)
public virtual void OnCompleted()
public virtual void Unsubscribe()
Console.WriteLine("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
public class HeatIndexDisplay : IDisplayElement, IObserver<WeatherDataInfo>
private float temperature;
private IDisposable cancellation;
public virtual void OnError(Exception e)
public virtual void OnCompleted()
public virtual void Unsubscribe()
public HeatIndexDisplay(WeatherDataHandler provider)
cancellation = provider.Subscribe(this);
public virtual void OnNext(WeatherDataInfo value)
this.temperature = value.Temperature;
this.humidity = value.Humidity;
this.heatIndex = computeHeatIndex(temperature, humidity);
private float computeHeatIndex(float t, float rh) {
float index = (float)((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) +
(0.00941695 * (t * t)) + (0.00728898 * (rh * rh)) +
(0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
(0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
(rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
(0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
0.000000000843296 * (t * t * rh * rh * rh)) -
(0.0000000000481975 * (t * t * t * rh * rh * rh)));
Console.WriteLine("Heat index is " + heatIndex);