C# observer mode

Programming requirements

The weather station will provide us with data on temperature, humidity and pressure. Among them, four weather forecast software companies have subscribed. They provide different weather services according to the weather data. In this example, the four companies require the Meteorological Bureau to provide a unified interface and update the data in real time. Please complete the code from begin to end in the code area on the right. The original code cannot be modified.

Input format:
The first line of input gives a positive integer n (n ⩽ 10) indicating the batch of data update. Then n lines, each line gives 3 real numbers (temperature, humidity and air pressure), separated by half width commas.

Output format:
Output the output of four meteorological software n times.

Input sample:
3
80.0,65.0,30.4
82.0,70.0,29.2
78.0,90.0,29.2

Output example:
Status quo: 80F degrees and 65% humidity
Average / maximum / minimum temperature = 80 / 80 / 80
Forecast: the temperature is rising
Heat index 82.95535
Status quo: 82F degrees and 70% humidity
Average / maximum / minimum temperature = 81 / 82 / 80
Forecast: the temperature is getting cool
Heat index 86.90123
Status quo: 78F degrees and 90% humidity
Average / maximum / minimum temperature = 80 / 82 / 78
Forecast: no change in temperature
Heat index 83.64967

Relevant knowledge

concept
When there is a one to many relationship between objects, the Observer Pattern is used. For example, when an object is modified, its dependent objects will be automatically notified. Observer mode belongs to behavioral mode.

Structure of pattern
The main roles of the observer model are as follows.

Abstract Subject role: also known as abstract target class, it provides an aggregation class for saving observer objects, methods for adding and deleting observer objects, and abstract methods for notifying all observers.
Concrete Subject role: also known as concrete target class, it implements the notification method in the abstract target. When the internal state of the specific subject changes, it notifies all registered observer objects.
Abstract Observer role: it is an abstract class or interface, which contains an abstract method to update itself. It is called when receiving the change notification of a specific topic.
When the observer's abstract method is changed, the observer will be notified of the change of the observer's abstract method.
The structure of observer mode is shown in Figure 1.

Problems that can be solved
The problem of notifying other objects of an object's state change should be considered, and the ease of use and low coupling should be considered to ensure a high degree of cooperation.

The most appropriate case
Magazine subscription, magazine is the theme, and the observer is the subscriber. When a new magazine is published, this event will automatically notify all subscribers.

code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace F1
{
    class Program
    {
        static void Main(string[] args)
        {
            /********** Begin *********/
            int n = Convert.ToInt32(Console.ReadLine());
            WeatherData data = new WeatherData();
            data.RegisterObserver(new CurrentConditionsDisplay());
            data.RegisterObserver(new StatisticsDisplay());
            data.RegisterObserver(new ForecastDisplay());
            data.RegisterObserver(new HeatIndexDisplay());
            for (int i = 0; i < n; i++)
            {
                string str = Console.ReadLine();
                string[] arr = str.Split(',');
                data.setMeasurements(arr[0], arr[1], arr[2]);
            }

            /********** End *********/
        }
    }
    interface ISubject
    {
        void RegisterObserver(IObserver o);//Registered observer
        void RemoveObserver(IObserver o);//Logout observer
        void notifyObservers();///Notify the observer when the data changes
    }
    interface IObserver
    {
        void Update(float temp, float humidity, float pressure);
    }
    interface IDisplayElement
    {
        void display();
    }
    class WeatherData : ISubject
    {
        private float temperature;//temperature
        private float humidity;//humidity
        private float pressure;//pressure
        private List<IObserver> observers;//Observer List, which is used to store all observers
        public float Temperature { get { return temperature; } }
        public float Humidity { get { return humidity; } }
        public float Pressure { get { return pressure; } }
        public WeatherData()
        {
            observers = new List<IObserver>();
        }

        public void RegisterObserver(IObserver o)
        {
            /********** Begin *********/
               observers.Add(o);

            /********** End *********/
        }
        public void RemoveObserver(IObserver o)
        {
            int i = observers.IndexOf(o);
            /********** Begin *********/
              observers.RemoveAt(i);

            /********** End *********/
        }
        public void notifyObservers()
        {
            /********** Begin *********/
            foreach(IObserver o in observers)
                o.Update(temperature, humidity, pressure);

            /********** End *********/
        }

        public void setMeasurements(string temperature, string humidity, string pressure)
        {
            float temp;
            float.TryParse(temperature, out temp);
            this.temperature = temp;
            float.TryParse(humidity, out temp);
            this.humidity = temp;
            float.TryParse(pressure, out temp);
            this.pressure = temp;
            measurementsChanged();
        }
        public void measurementsChanged()
        {
            notifyObservers();
        }

    }
    class CurrentConditionsDisplay : IObserver, IDisplayElement
    {
        private float temperature;
        private float humidity;

        public void Update(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
        public void display()
        {
            Console.WriteLine("present situation: " + temperature + "F Degree sum" + humidity + "% humidity");
        }
    }
    class ForecastDisplay : IObserver, IDisplayElement
    {
        private float currentPressure = 29.92f;
        private float lastPressure;
        public void Update(float temp, float humidity, float pressure)
        {
            lastPressure = currentPressure;
            currentPressure = pressure;
            display();
        }
        public void display()
        {
            Console.Write("forecast: ");
            if (currentPressure > lastPressure) { Console.Write("The temperature is rising\n"); }
            else if (currentPressure == lastPressure) { Console.Write("The temperature has not changed\n"); }
            else if (currentPressure < lastPressure) { Console.Write("The temperature is getting cool\n"); }
        }
    }
    class HeatIndexDisplay : IObserver, IDisplayElement
    {
        float heatIndex = 0.0f;
        public void Update(float t, float rh, float pressure)
        {
            heatIndex = computeHeatIndex(t, rh);
            display();
        }
        public void display()
        {
            Console.WriteLine("Thermal index " + heatIndex);
        }
        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)));
            return index;
        }
    }
    class StatisticsDisplay : IObserver, IDisplayElement
    {
        private float maxTemp = 0.0f;
        private float minTemp = 200;
        private float tempSum = 0.0f;
        private int numReadings;
        public void display()
        {
            Console.WriteLine("average/highest/Minimum temperature = " + (tempSum / numReadings) + "/" + maxTemp + "/" + minTemp);
        }

        public void Update(float temp, float humidity, float pressure)
        {
            tempSum += temp;
            numReadings++;
            if (temp > maxTemp)
            {
                maxTemp = temp;
            }
            if (temp < minTemp)
            {
                minTemp = temp;
            }
            display();
        }
    }
}

Tags: C# programming language

Posted by freelancer on Sat, 21 May 2022 00:44:08 +0300