Observer Pattern
#region Interfaces
public interface ISubject
{
public void RegisterOb(IObserver o);
public void RemoveOb(IObserver o);
public void NotifyOb();
}
public interface IObserver
{
public void Update(WeatherData wd);
}
public interface IDisplay
{
public void Display();
}
#endregion
#region BaseClasses
public struct WeatherData
{
private float temp;
private float humidity;
private float pressure;
public WeatherData(float temp, float humidity, float pressure)
{
this.temp = temp;
this.humidity = humidity;
this.pressure = pressure;
}
public float GetTemp() { return temp; }
public float GetHumidity() { return humidity; }
public float GetPressure() { return pressure; }
}
public class DataController : ISubject
{
private List<IObserver> observers;
private WeatherData wd;
public DataController()
{
observers = new List<IObserver>();
}
public void RegisterOb(IObserver o) { observers.Add(o); }
public void RemoveOb(IObserver o) { observers.Remove(o); }
public void NotifyOb() { foreach (var o in observers) o.Update(wd); }
public void MeasurementsChanged() { NotifyOb(); }
public void SetMeasurements(float temp, float humidity, float pressure) { wd = new WeatherData(temp, humidity, pressure); MeasurementsChanged(); }
}
#endregion
#region DisplayClasses
public class CurrentConditionDisplay : IObserver, IDisplay
{
private float temperature;
private float humidity;
private DataController dc;
public CurrentConditionDisplay(DataController dc)
{
this.dc = dc;
dc.RegisterOb(this);
}
public void Update(WeatherData wd)
{
this.temperature = wd.GetTemp();
this.humidity = wd.GetHumidity();
Display();
}
public void Display() { Console.WriteLine($"Current conditions: {temperature}F degrees and {humidity}% humidity"); }
}
#endregion
public class WeatherStation
{
public static void Main(String[] args)
{
DataController dc = new DataController();
CurrentConditionDisplay ccd = new CurrentConditionDisplay(dc);
dc.SetMeasurements(80, 65, 30.4f);
dc.SetMeasurements(70, 55, 20.4f);
dc.SetMeasurements(60, 45, 10.4f);
}
}
옵저버가 데이터를 pull하는 형식으로 변경하려면, 수정사항은 아래와 같다.
public interface IObserver
{
public void Update();
}
public void NotifyOb() { foreach (var o in observers) o.Update(); }
public void Update()
{
this.temperature = dc.wd.GetTemp();
this.humidity = dc.wd.GetHumidity();
Display();
}