Machine Coding Problem

Smart Home System

maco60macoAlliotcommand-&-composite-patternsstate-synchronizationobserver-registrybounded-history-logs
Commonly Asked By:AppleGoogleAmazon

Requirements & System Scope

Functional Scope (In-Scope)

  • Executable & Reversible Commands: Support executing and undoing operations via slot-to-command registries.
  • Composite Scene Macros: Trigger grouped device operations simultaneously (e.g., a "Good Night" scene).
  • Observer Monitoring Status: Keep telemetry listeners updated on all device actions.
  • Thread Safe Operations State: Synchronize concurrent requests across remote keys, schedules, and observers.

Explicit Boundaries (Out-of-Scope)

  • No electrical driver code signals: Bypasses raw IoT Zigbee or Z-Wave hardware register maps.
  • No dynamic network connectivity check: Excludes handling router socket disconnections or wireless drops.

Class Diagram & Entity Relationships

Class relations showing remote slots, scene commands, and observers:

Loading...

Design Patterns & SOLID Principles

  • Command Pattern (Device Operations): Decouples the RemoteControl sender from individual SmartDevice execution logic, providing easy undo histories and scheduled executions.
  • Composite Pattern (Scene Macros): Allows multiple commands to bundle into a single MacroCommand that behaves exactly like a single unit.

Core Execution Workflows

Scene Presets & Undo Cycle

  1. Client triggers the "Good Night" macro scene: remote.executeCommand(goodNightScene).
  2. The MacroCommand executes its sub-commands (e.g. lock front door, dim hall lights) in sequence.
  3. Each sub-command triggers state adjustments on its corresponding receiver device.
  4. Devices notify registered observers of telemetry state adjustments.
  5. The remote pushes the macro onto its history log. If the user invokes undoLastCommand(), pop the macro and undo actions in reverse.

Concurrency & Thread Safety Strategy

When multiple family members control devices simultaneously via remote, schedules, or voice input:

  • Synchronized State Locks: Wrap device state adjustments inside localized lock blocks to prevent parameter corruption.
  • Thread-Safe History Stack: Guard remote command logs inside thread-safe array double queues.

Complete Clean Code Blueprint

Clean reference designs demonstrating Command patterns in Java and Python:

// โ”€โ”€โ”€ JAVA BLUEPRINT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

interface DeviceObserver {
    void onDeviceStateChanged(String deviceName, String newState);
}

interface SmartDevice {
    String getName();
    String getStatus();
}

class SmartLight implements SmartDevice {
    private final String name;
    private boolean isOn = false;
    private int brightness = 100;
    private final ReentrantLock lock = new ReentrantLock();
    private final List<DeviceObserver> observers = new CopyOnWriteArrayList<>();

    public SmartLight(String name) { this.name = name; }
    public void addObserver(DeviceObserver obs) { observers.add(obs); }

    public void turnOn() {
        lock.lock();
        try {
            this.isOn = true;
            notifyObservers();
        } finally {
            lock.unlock();
        }
    }

    public void turnOff() {
        lock.lock();
        try {
            this.isOn = false;
            notifyObservers();
        } finally {
            lock.unlock();
        }
    }

    public void setBrightness(int level) {
        lock.lock();
        try {
            this.brightness = Math.max(0, Math.min(100, level));
            notifyObservers();
        } finally {
            lock.unlock();
        }
    }

    public boolean isOn() { return isOn; }
    public int getBrightness() { return brightness; }

    private void notifyObservers() {
        String status = getStatus();
        for (DeviceObserver obs : observers) obs.onDeviceStateChanged(name, status);
    }

    @Override public String getName() { return name; }
    @Override public String getStatus() { return "Light is " + (isOn ? "ON" : "OFF") + ", Brightness: " + brightness + "%"; }
}

class SmartLock implements SmartDevice {
    private final String name;
    private boolean isLocked = true;
    private final ReentrantLock lock = new ReentrantLock();
    private final List<DeviceObserver> observers = new CopyOnWriteArrayList<>();

    public SmartLock(String name) { this.name = name; }
    public void addObserver(DeviceObserver obs) { observers.add(obs); }

    public void lock() {
        lock.lock();
        try {
            this.isLocked = true;
            notifyObservers();
        } finally {
            lock.unlock();
        }
    }

    public void unlock() {
        lock.lock();
        try {
            this.isLocked = false;
            notifyObservers();
        } finally {
            lock.unlock();
        }
    }

    public boolean isLocked() { return isLocked; }

    private void notifyObservers() {
        String status = getStatus();
        for (DeviceObserver obs : observers) obs.onDeviceStateChanged(name, status);
    }

    @Override public String getName() { return name; }
    @Override public String getStatus() { return "Lock is " + (isLocked ? "LOCKED" : "UNLOCKED"); }
}

interface Command {
    void execute();
    void undo();
}

class LightOnCommand implements Command {
    private final SmartLight light;
    private int prevBrightness;

    public LightOnCommand(SmartLight light) { this.light = light; }

    @Override
    public void execute() {
        prevBrightness = light.getBrightness();
        light.turnOn();
    }

    @Override
    public void undo() {
        light.turnOff();
        light.setBrightness(prevBrightness);
    }
}

class LightOffCommand implements Command {
    private final SmartLight light;
    private boolean wasOn;

    public LightOffCommand(SmartLight light) { this.light = light; }

    @Override
    public void execute() {
        wasOn = light.isOn();
        light.turnOff();
    }

    @Override
    public void undo() {
        if (wasOn) light.turnOn();
    }
}

class LockCommand implements Command {
    private final SmartLock smartLock;
    private boolean wasLocked;

    public LockCommand(SmartLock smartLock) { this.smartLock = smartLock; }

    @Override
    public void execute() {
        wasLocked = smartLock.isLocked();
        smartLock.lock();
    }

    @Override
    public void undo() {
        if (!wasLocked) smartLock.unlock();
    }
}

class UnlockCommand implements Command {
    private final SmartLock smartLock;
    private boolean wasLocked;

    public UnlockCommand(SmartLock smartLock) { this.smartLock = smartLock; }

    @Override
    public void execute() {
        wasLocked = smartLock.isLocked();
        smartLock.unlock();
    }

    @Override
    public void undo() {
        if (wasLocked) smartLock.lock();
    }
}

class MacroCommand implements Command {
    private final List<Command> commands;

    public MacroCommand(List<Command> commands) {
        this.commands = new ArrayList<>(commands);
    }

    @Override
    public void execute() {
        for (Command cmd : commands) cmd.execute();
    }

    @Override
    public void undo() {
        for (int i = commands.size() - 1; i >= 0; i--) {
            commands.get(i).undo();
        }
    }
}

class RemoteControl {
    private final Deque<Command> history = new ArrayDeque<>();
    private final int maxHistorySize = 10;
    private final ReentrantLock historyLock = new ReentrantLock();

    public void executeCommand(Command cmd) {
        cmd.execute();
        historyLock.lock();
        try {
            if (history.size() >= maxHistorySize) {
                history.pollFirst();
            }
            history.addLast(cmd);
        } finally {
            historyLock.unlock();
        }
    }

    public void undoLastCommand() {
        historyLock.lock();
        try {
            if (!history.isEmpty()) {
                Command cmd = history.removeLast();
                cmd.undo();
            }
        } finally {
            historyLock.unlock();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("=== Advanced Smart Home System ===");
        DeviceObserver logger = (dev, state) -> System.out.println("[Telemetry] " + dev + " -> " + state);

        SmartLight livingRoomLight = new SmartLight("Living Room Light");
        SmartLock frontDoorLock = new SmartLock("Front Door Lock");

        livingRoomLight.addObserver(logger);
        frontDoorLock.addObserver(logger);

        RemoteControl remote = new RemoteControl();

        System.out.println("\n--- Execute Single Command ---");
        remote.executeCommand(new LightOnCommand(livingRoomLight));

        System.out.println("\n--- Execute Scene Macro ---");
        List<Command> goodNightOps = Arrays.asList(
                new LightOffCommand(livingRoomLight),
                new LockCommand(frontDoorLock)
        );
        remote.executeCommand(new MacroCommand(goodNightOps));

        System.out.println("\n--- Undo Last Scene Macro ---");
        remote.undoLastCommand();
    }
}

๐Ÿ’ฌReview

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...