Weather Data Code


This entry is part 2 of 2 in the series Observer Pattern

This post continues from the previous post. The list of posts can be seen on the right side of this text.

Below is the XAML listing for the WPF program that I called ObserveWeather. The code in the book Head First Design Patterns is written in Java, but C# so similar that I was able to write it in C# easily. Feel free to use the code below to create your own program.

<Window x:Class="ObserveWeather.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ObserveWeather"
        mc:Ignorable="d"
        Title="Head First Design Patterns - Chapter 2 Observer Pattern" Height="250" Width="480">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <StackPanel>
                <TextBlock FontSize="14" FontWeight="Bold">Current Conditions</TextBlock>
                <TextBlock x:Name="txtblk01"></TextBlock>
                <TextBlock x:Name="txtblk02"></TextBlock>
                <TextBlock x:Name="txtblk03"></TextBlock>
            </StackPanel>
        </Grid>
        <Grid Grid.Row="1">
            <StackPanel>
                <TextBlock FontSize="14" FontWeight="Bold">Phone Display</TextBlock>
                <TextBlock x:Name="txtblk11"></TextBlock>
                <TextBlock x:Name="txtblk12"></TextBlock>
                <TextBlock x:Name="txtblk13"></TextBlock>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

Below is the code behind in the file MainWindow.xaml.cs.

using System.Windows;
namespace ObserveWeather
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            WeatherData weatherData = new WeatherData();
            CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
            PhoneDisplay phoneDisplay = new PhoneDisplay(weatherData);

            weatherData.setMeasurements(80f, 65f, 30.4f);
        }
    }
}

Below is the interface ISubject.cs.

namespace ObserveWeather
{
    public interface ISubject
    {
        public void registerObserver(IObserver o);
        public void removeObserver(IObserver o);
        public void notifyObservers();
    }
}

Below is the interface IObserver.cs.

namespace ObserveWeather
{
    public interface IObserver
    {
        public void update(float temp, float humidity, float pressure);
    }
}

Below is the interface IDisplayElement.cs.

namespace ObserveWeather
{
    public interface IDisplayElement
    {
        public void display();
    }
}

Below is the code for WeatherData.cs.

using System.Collections.Generic;
namespace ObserveWeather
{
    public class WeatherData : ISubject  // implements ISubject interface
    {
        private List<IObserver> observers;  // in Java: ArrayList()
        private float temperature;
        private float humidity;
        private float pressure;

        public WeatherData()
        {   // constructor
            observers = new List<IObserver>();
        }
        public void registerObserver(IObserver o)
        {
            observers.Add(o);
        }
        public void removeObserver(IObserver o)
        {
            int i = observers.IndexOf(o);
            if (i >= 0) observers.RemoveAt(i);  // if found remove it
        }
        public void notifyObservers()
        {
            //for (int i = 0; i < observers.Count; i++)
            //{
            //    IObserver observer = (IObserver)observers[i];
            //    observer.update(temperature, humidity, pressure);
            //}
            foreach (IObserver o in this.observers)
            {
                o.update(temperature, humidity, pressure);
            }
        }
        public void measurementsChanged()
        {
            notifyObservers();
        }
        public void setMeasurements(float temperature, float humidity, float pressure)
        {
            // use this method to test it.
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            measurementsChanged();
        }
    }
}

CurrentConditionDisplay.cs

using System.Windows;
namespace ObserveWeather
{
    public class CurrentConditionsDisplay : IObserver, IDisplayElement
    {
        private float temperature;
        private float humidity;
        private ISubject weatherData;
        
        public CurrentConditionsDisplay (ISubject weatherData)
        {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
        public void update(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
        public void display()
        {
            foreach (Window window in Application.Current.Windows)
            {
                if (window.GetType() == typeof(MainWindow))
                {
                    (window as MainWindow).txtblk01.Text = temperature.ToString();
                    (window as MainWindow).txtblk02.Text = humidity.ToString();
                }
            }
        }
    }
}

PhoneDisplay.cs

using System.Windows;
namespace ObserveWeather
{
    class PhoneDisplay : IObserver, IDisplayElement
    {
        private float temperature;
        private float humidity;
        private ISubject weatherData;

        public PhoneDisplay(ISubject weatherData)
        {   // constructor
            this.weatherData = weatherData;
            weatherData.registerObserver(this);      
        }
        public void update(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
        public void display()
        {
            foreach (Window window in Application.Current.Windows)
            {
                if (window.GetType() == typeof(MainWindow))
                {
                    (window as MainWindow).txtblk11.Text = temperature.ToString();
                    (window as MainWindow).txtblk12.Text = humidity.ToString();
                }
            }
        }
    }
}
Series Navigation<< Observer Pattern Weather Introduction