Ready to tackle the next part of our smart home system project? This unit focuses on two more essential design patterns: Observer and Strategy. These patterns will enhance our system's functionality by enabling responsive security and flexible climate control.
Let’s refresh and build upon our project with these patterns.
First, we will use the Observer pattern to develop our smart home security system. This pattern will allow multiple home elements (like your mobile app) to respond to intrusion alerts from the security system.
Next, we will employ the Strategy pattern to create a flexible climate control system. This will let us change the way we control the temperature (heating or cooling) based on the strategy selected, ensuring that we can easily switch between different climate control models.
Great! Let’s move forward and start implementing these components.
To implement the Observer pattern in C#, we'll define an interface IObserver
which will be implemented by any class that needs to be notified about security alerts. The Subject
class will manage observers and notify them of any changes.
Let's go through a step-by-step implementation!
Start by defining the IObserver
interface and the Subject
class. The IObserver
interface includes a method for updating observers, and the Subject
class will handle attaching, detaching, and notifying observers.
C#1public interface IObserver 2{ 3 void Update(string message); 4} 5 6public class Subject 7{ 8 private List<IObserver> observers = new List<IObserver>(); 9 10 public void Attach(IObserver observer) 11 { 12 observers.Add(observer); 13 } 14 15 public void Detach(IObserver observer) 16 { 17 observers.Remove(observer); 18 } 19 20 public void Notify(string message) 21 { 22 foreach (var observer in observers) 23 { 24 observer.Update(message); 25 } 26 } 27}
Next, we create the SecuritySystem
class inheriting from Subject
and the HomeOwner
class implementing IObserver
. The SecuritySystem
will notify the HomeOwner
instances when an intrusion is detected.
C#1public class SecuritySystem : Subject 2{ 3 public void DetectIntrusion() 4 { 5 Notify("Intrusion detected!"); 6 } 7} 8 9public class HomeOwner : IObserver 10{ 11 private string name; 12 13 public HomeOwner(string name) 14 { 15 this.name = name; 16 } 17 18 public void Update(string message) 19 { 20 Console.WriteLine($"{name} received message: {message}"); 21 } 22}
Finally, we integrate and test the Observer pattern by simulating an intrusion alert. The MainProgram
class demonstrates attaching homeowners to the security system and notifying them of an intrusion.
C#1public class Program 2{ 3 static void Main() 4 { 5 // Create instances of SecuritySystem and HomeOwner 6 SecuritySystem securitySystem = new SecuritySystem(); 7 HomeOwner owner1 = new HomeOwner("Alice"); 8 HomeOwner owner2 = new HomeOwner("Bob"); 9 10 // Attach observers to the security system 11 securitySystem.Attach(owner1); 12 securitySystem.Attach(owner2); 13 14 // Simulate detecting an intrusion 15 securitySystem.DetectIntrusion(); 16 // Output: Alice received message: Intrusion detected! 17 // Bob received message: Intrusion detected! 18 19 // Detach one observer and simulate another intrusion 20 securitySystem.Detach(owner1); 21 securitySystem.DetectIntrusion(); 22 // Output: Bob received message: Intrusion detected! 23 } 24}
In this example, our security system notifies homeowners (observers) whenever an intrusion is detected.
The Strategy pattern allows us to change the algorithm used for controlling the climate at runtime. We'll define an interface IClimateControl
for climate control strategies and implement specific strategies for heating and cooling.
Let's go through a step-by-step implementation!
First, define the IClimateControl
interface and create implementations for the heating and cooling strategies.
C#1public interface IClimateControl 2{ 3 void AdjustTemperature(int temperature); 4} 5 6public class Heating : IClimateControl 7{ 8 public void AdjustTemperature(int temperature) 9 { 10 Console.WriteLine($"Heating the room to {temperature} degrees."); 11 } 12} 13 14public class Cooling : IClimateControl 15{ 16 public void AdjustTemperature(int temperature) 17 { 18 Console.WriteLine($"Cooling the room to {temperature} degrees."); 19 } 20}
Next, create the ClimateController
class that will use the selected climate control strategy to adjust the temperature.
C#1public class ClimateController 2{ 3 private IClimateControl? control; 4 5 public void SetClimateControl(IClimateControl control) 6 { 7 this.control = control; 8 } 9 10 public void AdjustTemperature(int temperature) 11 { 12 if (control != null) 13 { 14 control.AdjustTemperature(temperature); 15 } 16 else 17 { 18 Console.WriteLine("Climate control not set!"); 19 } 20 } 21}
Finally, we integrate and test the Strategy pattern by switching between heating and cooling strategies. The MainProgram
class demonstrates setting and using different climate control strategies.
C#1public class Program 2{ 3 static void Main() 4 { 5 // Create a climate controller and strategies 6 ClimateController controller = new ClimateController(); 7 IClimateControl heating = new Heating(); 8 IClimateControl cooling = new Cooling(); 9 10 // Set the heating strategy and adjust the temperature 11 controller.SetClimateControl(heating); 12 controller.AdjustTemperature(70); 13 // Output: Heating the room to 70 degrees. 14 15 // Set the cooling strategy and adjust the temperature 16 controller.SetClimateControl(cooling); 17 controller.AdjustTemperature(65); 18 // Output: Cooling the room to 65 degrees. 19 } 20}
In this example, our climate controller can dynamically switch between heating and cooling strategies to adjust the temperature.
With these implementations, your smart home system will be more responsive and flexible, adapting to various scenarios by using design patterns effectively. Happy coding!