← → or space · progress saves for Continue on the roadmap
Goal
Notify multiple listeners when state changes without hard-wiring each subscriber into the model.
Step 1 - Listener list
class ObservableCounter {
int _value = 0;
final List<void Function(int)> _listeners = [];
int get value => _value;
void addListener(void Function(int next) listener) {
_listeners.add(listener);
}
void removeListener(void Function(int next) listener) {
_listeners.remove(listener);
}
void increment() {
_value++;
for (final listener in List<void Function(int)>.from(_listeners)) {
listener(_value);
}
}
}
void main() {
final c = ObservableCounter();
c.addListener((v) => print('a $v'));
c.addListener((v) => print('b $v'));
c.increment();
}Step 2 - Stream-shaped (bonus)
import 'dart:async';
class CounterStream {
int _value = 0;
final _ctrl = StreamController<int>.broadcast();
int get value => _value;
Stream<int> get changes => _ctrl.stream;
void increment() {
_value++;
_ctrl.add(_value);
}
Future<void> close() => _ctrl.close();
}- Fits reactive APIs; remember to
closethe controller when the owner is disposed.
Tradeoffs
- Manual lists are simple; streams add async backpressure and
listen/cancelergonomics. - Avoid notifying during a listener callback if that callback mutates the same model unless you design for re-entrancy.
Practice tasks
- Add
void decrement()and ensure both listeners see consistent ordering. - Reimplement
ObservableCounterwith a singleStreamControllerand noListof functions. - Compare to
ChangeNotifierin Flutter (read docs only; no Flutter required here).