Applying Observer and Strategy Patterns for Smart Home Security System and Climate Control

This unit focuses on two design patterns: Observer and Strategy. We'll use these patterns to enable responsive security and flexible climate control in our smart home system.

Quick Summary
  1. Observer Pattern:

    • Purpose: Allows an object (observer) to watch another (subject) and get notified of changes.
    • Steps:
      • Define a Subject with registration, unregistration, and notification methods (e.g., for a SecuritySystem).
      • Implement observers that react to changes (e.g., SecurityApp, SecurityLight).
  2. Strategy Pattern:

    • Purpose: Defines a family of algorithms and makes them interchangeable.
    • Steps:
      • Define a strategy interface with a method for the desired behavior (e.g., TemperatureControlStrategy for controlling temperature).
      • Implement specific strategies with concrete behavior (e.g., HeatingStrategy, CoolingStrategy).
      • Create a context to use and switch strategies (e.g., a ClimateControl system).
Implementing the Observer Pattern for the Security System

Here is the complete code to implement the Observer pattern:

# Define the Subject class
class Subject:
    def __init__(self):
        self.__observers = []

    def register_observer(self, observer):
        self.__observers.append(observer)

    def unregister_observer(self, observer):
        self.__observers.remove(observer)

    def notify_observers(self):
        for observer in self.__observers:
            observer.update(self)

# Define the SecuritySystem class
class SecuritySystem(Subject):
    def __init__(self):
        super().__init__()
        self.__state = None

    def set_state(self, state):
        self.__state = state
        self.notify_observers()
        
    def get_state(self):
        return self.__state

# Define the Observer interface
class Observer:
    def update(self, subject):
        pass

# Implement the SecurityApp observer
class SecurityApp(Observer):
    def update(self, subject):
        if isinstance(subject, SecuritySystem):
            print(f"SecurityApp notified. New state: {subject.get_state()}")

# Implement the SecurityLight observer
class SecurityLight(Observer):
    def update(self, subject):
        if isinstance(subject, SecuritySystem):
            print(f"SecurityLight activated! State: {subject.get_state()}")

# Example usage
security_system = SecuritySystem()
app = SecurityApp()
light = SecurityLight()
security_system.register_observer(app)
security_system.register_observer(light)
security_system.set_state("Intrusion Detected")

# Expected Output:
# SecurityApp notified. New state: Intrusion Detected
# SecurityLight activated! State: Intrusion Detected

The security_system instance notifies both SecurityApp and SecurityLight when the state changes to "Intrusion Detected".

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal