Observer
What is the Observer Pattern?
The Observer Pattern is a behavioral design pattern used to create a one-to-many dependency between objects. When one object (the subject) changes its state, all its dependents (observers) are automatically notified and updated.
It is also known as Publish-Subscribe or Event Listener pattern.
Why Use Observer in FRC Robot Code?
Robotics is highly event-driven: sensors change, user inputs happen, and robot states update constantly. The Observer pattern helps by:
Decoupling event sources from event handlers.
Allowing multiple parts of code (observers) to react to changes without tight coupling.
Keeping your code modular and maintainable.
Making asynchronous or reactive programming easier, like reacting to joystick buttons or sensor triggers.
Facilitating communication between subsystems and dashboard updates.
Core Concepts
Subject: The object holding state or events that observers want to watch.
Observer: Objects that subscribe to the subject to get notified of state changes.
Notification: When the subject changes, it calls each observer’s update method.
Typical Use Cases in FRC
Sensor Monitoring: Observers react when a sensor value crosses a threshold.
Joystick/Button Events: Buttons act as subjects that notify commands or subsystems.
Robot State Changes: Observers update dashboard or loggers when mode changes.
Vision Processing: Vision subsystem publishes detected targets; other code reacts.
Subsystem Feedback: E.g., Elevator position changes notify other parts of code.
Example: Simple Observer Implementation for Sensor Changes
Step 1: Define the Observer interface
public interface Observer {
void update();
}
Step 2: Define the Subject interface
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
Step 3: Implement a concrete Subject — e.g., a LimitSwitch sensor wrapper
import java.util.ArrayList;
import java.util.List;
public class LimitSwitch implements Subject {
private boolean state;
private final List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer o : observers) {
o.update();
}
}
public void setState(boolean newState) {
if (state != newState) {
state = newState;
notifyObservers();
}
}
public boolean getState() {
return state;
}
}
Step 4: Implement an Observer — e.g., a command or subsystem watching the switch
public class ElevatorController implements Observer {
private final LimitSwitch limitSwitch;
public ElevatorController(LimitSwitch limitSwitch) {
this.limitSwitch = limitSwitch;
limitSwitch.registerObserver(this);
}
@Override
public void update() {
if (limitSwitch.getState()) {
System.out.println("Limit switch activated! Stopping elevator.");
// Stop elevator motor here
}
}
}
Last updated