i_spy 1.0.0 i_spy: ^1.0.0 copied to clipboard
Visionary Software Solutions iSpy ==> OBSERVER, MEDIATOR, and Eventing Done Right.
import 'dart:math';
import 'package:i_spy/i_spy.dart';
final class Ping implements Event {}
final class Pong implements Event {}
final fate = Random();
final class Pinger implements Observable<Event>, Observer<Event> {
Pinger() {
SimpleEventingSystem.instance.add(this);
}
@override
void notifyObservers(Event e) {
SimpleEventingSystem.instance.notifyObservers(e);
}
void ping() => notifyObservers(Ping());
@override
void update(final Event e) {
if (e is Pong) {
if (fate.nextBool()) {
ping();
}
}
}
}
final class Scribe implements Observer<Event> {
Scribe() {
SimpleEventingSystem.instance.add(this);
}
@override
void update(final Event e) {
print(e.runtimeType);
}
}
final class Ponger implements Observable<Event>, Observer<Event> {
Ponger() {
SimpleEventingSystem.instance.add(this);
}
@override
void notifyObservers(final Event e) {
SimpleEventingSystem.instance.notifyObservers(e);
}
@override
void update(final Event e) {
if (e is Ping) {
if (fate.nextBool()) {
pong();
}
}
}
void pong() => notifyObservers(Pong());
}
final class Finished implements Event {}
void main() {
/// Basic demonstration of how OBSERVER and MEDIATOR enable decoupling between
/// two components. [Pinger] and [Ponger] don't know about each other.
final ping = Pinger();
final pong = Ponger();
final scribe = Scribe();
/// nor do they know that there's a [Scribe] jotting down what happens.
/// This loose coupling is a boon in many UI contexts.
ping.ping();
pong.pong();
scribe.update(Finished());
/// This example only showed a [SimpleEventingSystem] which allows all types
/// of [Event]. Generic constrained versions of [Observer], [Observable], and
/// [Mediator] are available for times when one doesn't mind having more
/// instances around to ensure type safety. Check out the unit tests for more.
}