Applying Observer and Strategy Patterns for Smart Home Systems

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 using JavaScript:

// Define the Subject class
class Subject {
    constructor() {
        this._observers = [];
    }

    registerObserver(observer) {
        this._observers.push(observer);
    }

    unregisterObserver(observer) {
        this._observers = this._observers.filter(obs => obs !== observer);
    }

    notifyObservers() {
        this._observers.forEach(observer => observer.update(this));
    }
}

// Define the SecuritySystem class
class SecuritySystem extends Subject {
    constructor() {
        super();
        this._state = null;
    }

    setState(state) {
        this._state = state;
        this.notifyObservers();
    }
    
    getState() {
        return this._state;
    }
}

// Define the Observer interface
class Observer {
    update(subject) {
        throw new Error('Observer update method must be implemented.');
    }
}

// Implement the SecurityApp observer
class SecurityApp extends Observer {
    update(subject) {
        if (subject instanceof SecuritySystem) {
            console.log(`SecurityApp notified. New state: ${subject.getState()}`);
        }
    }
}

// Implement the SecurityLight observer
class SecurityLight extends Observer {
    update(subject) {
        if (subject instanceof SecuritySystem) {
            console.log(`SecurityLight activated! State: ${subject.getState()}`);
        }
    }
}

// Example usage
const securitySystem = new SecuritySystem();
const app = new SecurityApp();
const light = new SecurityLight();
securitySystem.registerObserver(app);
securitySystem.registerObserver(light);
securitySystem.setState("Intrusion Detected");

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

The securitySystem 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