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