diff --git a/Ch2Weather/Ch2Weather.csproj b/Ch2Weather/Ch2Weather.csproj new file mode 100644 index 0000000..46e6c92 --- /dev/null +++ b/Ch2Weather/Ch2Weather.csproj @@ -0,0 +1,11 @@ + + + + Exe + net9.0 + latestmajor + enable + enable + + + diff --git a/Ch2Weather/Exercise1.mermaid b/Ch2Weather/Exercise1.mermaid new file mode 100644 index 0000000..c9aec06 --- /dev/null +++ b/Ch2Weather/Exercise1.mermaid @@ -0,0 +1,38 @@ +classDiagram + class WeatherData { + getTemperature() + getHumidity() + getPressure() + measurementsChanged() + + subscribe(observer: IWeatherObserver) + unsubscribe(observer: IWeatherObserver) + notify(data: WeatherRecord) + } + class WeatherRecord { + f32 temperature + f32 humidity + f32 pressure + } + class IWeatherObserver { + update(data: WeatherRecord) + } + class IWeatherSubject { + subscribe(observer: IWeatherObserver) + unsubscribe(observer: IWeatherObserver) + notify(data: WeatherRecord) + } + class WeatherScreen1 { + update(data: WeatherRecord) + draw() + } + IWeatherSubject <|.. WeatherData + IWeatherObserver <|.. WeatherScreen1 + IWeatherObserver <-- IWeatherSubject : observers + WeatherData <-- WeatherScreen1 : Subjects + IWeatherObserver .. IWeatherSubject + class IDisplayElement { + draw() + } + IDisplayElement <|.. WeatherScreen1 + \ No newline at end of file diff --git a/Ch2Weather/Program.cs b/Ch2Weather/Program.cs new file mode 100644 index 0000000..c922dd9 --- /dev/null +++ b/Ch2Weather/Program.cs @@ -0,0 +1,10 @@ +// See https://aka.ms/new-console-template for more information + +using Ch2Weather; + +var weatherData = new WeatherData(new WeatherRecord(0, 0,0)); +_ = new CurrentConditionsDisplay(weatherData); +_ = new HeatIndexDisplay(weatherData); +weatherData.WeatherRecord = new WeatherRecord(25, 50, 30); +weatherData.WeatherRecord = new WeatherRecord(35, 55, 29.8); +weatherData.WeatherRecord = new WeatherRecord(45, 60, 29.6); \ No newline at end of file diff --git a/Ch2Weather/Weather.cs b/Ch2Weather/Weather.cs new file mode 100644 index 0000000..cd13504 --- /dev/null +++ b/Ch2Weather/Weather.cs @@ -0,0 +1,95 @@ +namespace Ch2Weather; + +public record struct WeatherRecord(double Temperature, double Humidity, double Pressure); + +public interface IWeatherSubject { + void Subscribe(IWeatherObserver o); + void Unsubscribe(IWeatherObserver o); + void NotifyObservers(); +} + +public interface IWeatherObserver { + void Update(WeatherRecord wr); +} + +public interface IWeatherDisplay { + void Display(); +} + +public class WeatherData(WeatherRecord weatherRecord) : IWeatherSubject { + private readonly List _observers = []; + private WeatherRecord _weatherRecord = weatherRecord; + + public WeatherRecord WeatherRecord { + get => _weatherRecord; + set { + _weatherRecord = value; + NotifyObservers(); + } + } + + public void Subscribe(IWeatherObserver o) { + _observers.Add(o); + } + + public void Unsubscribe(IWeatherObserver o) { + _observers.Remove(o); + } + + public void NotifyObservers() { + foreach (var o in _observers) { + o.Update(_weatherRecord); + } + } +} + +public class CurrentConditionsDisplay : IWeatherObserver, IWeatherDisplay { + private IWeatherSubject _subject; + private double _temperature = 0; + private double _humidity = 0; + + public CurrentConditionsDisplay(IWeatherSubject subject) { + _subject = subject; + subject.Subscribe(this); + } + + public void Update(WeatherRecord wr) { + _temperature = wr.Temperature; + _humidity = wr.Humidity; + Display(); + } + + public void Display() { + Console.WriteLine($"Current conditions: {_temperature}C degrees and {_humidity}% humidity."); + } +} + +public class HeatIndexDisplay : IWeatherObserver, IWeatherDisplay { + private IWeatherSubject _subject; + private WeatherRecord _weatherRecord = new WeatherRecord(0,0,0); + + public HeatIndexDisplay(IWeatherSubject subject) { + _subject = subject; + subject.Subscribe(this); + } + + private double ComputeHeatIndex(double t, double rh) { + return (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)); + } + public void Update(WeatherRecord wr) { + _weatherRecord = wr; + Display(); + } + + public void Display() { + var heatIndex = ComputeHeatIndex(_weatherRecord.Temperature, _weatherRecord.Humidity); + Console.WriteLine($"Heat Index is {heatIndex}"); + } +} \ No newline at end of file diff --git a/HeadFirstDesignPatterns.sln b/HeadFirstDesignPatterns.sln index 3b7b763..977f876 100644 --- a/HeadFirstDesignPatterns.sln +++ b/HeadFirstDesignPatterns.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch1Duck", "Ch1Duck\Ch1Duck.csproj", "{941002B3-4C8C-4A9A-9071-7FD27E9E5C9F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch2Weather", "Ch2Weather\Ch2Weather.csproj", "{D457D364-C0AB-42D2-A0B7-245D038CE8D1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {941002B3-4C8C-4A9A-9071-7FD27E9E5C9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {941002B3-4C8C-4A9A-9071-7FD27E9E5C9F}.Release|Any CPU.ActiveCfg = Release|Any CPU {941002B3-4C8C-4A9A-9071-7FD27E9E5C9F}.Release|Any CPU.Build.0 = Release|Any CPU + {D457D364-C0AB-42D2-A0B7-245D038CE8D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D457D364-C0AB-42D2-A0B7-245D038CE8D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D457D364-C0AB-42D2-A0B7-245D038CE8D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D457D364-C0AB-42D2-A0B7-245D038CE8D1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal