Design Pattern in Dart: Observer Pattern

The Observer Pattern is a core Behavioral Design Pattern that underpins many reactive programming principles — making it highly relevant to Flutter and Dart developers working with Streams, Providers, and State Management.

Here’s your full blog post (in English), complete with explanations and Dart code examples — ideal for your design pattern blog series.


Design Patterns in Dart: Observer Pattern

What is the Observer Pattern?

The Observer Pattern is a behavioral design pattern where an object (the subject) maintains a list of dependents (observers) and automatically notifies them of any state changes, usually by calling one of their methods.

In simpler terms:

“When the subject changes, all registered observers are notified.”


When to Use the Observer Pattern?

  • When you need to keep multiple objects in sync with one another.
  • When changes in one object should automatically trigger updates in others.
  • When implementing event-driven or reactive systems.

In Dart/Flutter, Observer pattern is the foundation for:

  • Stream / StreamController
  • ValueNotifier / ChangeNotifier
  • Provider, Bloc, Riverpod state management

Example in Dart: Weather Station Notifier

Scenario:

You’re building a weather station system that reports temperature updates.
Multiple display screens (observers) should update when the temperature changes.


Step 1: Define the Observer Interface

abstract class Observer {
void update(double temperature);
}

Step 2: Define the Subject Interface

abstract class Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}

Step 3: Implement the Concrete Subject (WeatherStation)

class WeatherStation implements Subject {
final List<Observer> _observers = [];
double _temperature = 0.0;

@override
void registerObserver(Observer observer) {
_observers.add(observer);
}

@override
void removeObserver(Observer observer) {
_observers.remove(observer);
}

@override
void notifyObservers() {
for (var observer in _observers) {
observer.update(_temperature);
}
}

void setTemperature(double temp) {
print("WeatherStation: Temperature updated to $temp°C");
_temperature = temp;
notifyObservers();
}
}

Step 4: Implement Observers (Display Devices)

class PhoneDisplay implements Observer {
@override
void update(double temperature) {
print("PhoneDisplay: Temperature is now $temperature°C");
}
}

class LEDDisplay implements Observer {
@override
void update(double temperature) {
print("LEDDisplay: Current temperature is $temperature°C");
}
}

Step 5: Client Code

void main() {
var station = WeatherStation();

var phone = PhoneDisplay();
var led = LEDDisplay();

station.registerObserver(phone);
station.registerObserver(led);

station.setTemperature(24.5);
station.setTemperature(30.0);

station.removeObserver(led);
station.setTemperature(18.0);
}

🧪 Output:

WeatherStation: Temperature updated to 24.5°C  
PhoneDisplay: Temperature is now 24.5°C
LEDDisplay: Current temperature is 24.5°C
WeatherStation: Temperature updated to 30.0°C
PhoneDisplay: Temperature is now 30.0°C
LEDDisplay: Current temperature is 30.0°C
WeatherStation: Temperature updated to 18.0°C
PhoneDisplay: Temperature is now 18.0°C

Benefits of the Observer Pattern

  • Promotes loose coupling between subject and observers.
  • Makes the system dynamic and extensible — you can add/remove observers anytime.
  • Great for event-driven applications.
  • Reduces dependencies by using an abstract interface.

Drawbacks

  • Can become complex when there are too many observers.
  • Risk of memory leaks if observers are not properly removed.
  • Debugging chains of events may be harder in large systems.

Flutter Use Cases

  • ValueNotifier and ChangeNotifier are direct implementations of the pattern.
  • State management libraries like:
    • Provider (with ChangeNotifier)
    • Riverpod (using reactive listeners)
    • Bloc (using Stream + Sink architecture)

Summary Table

AttributeObserver Pattern
PurposeNotify observers of subject changes
Common Use CasesUI updates, state management, event streams
Easy in Dart?✅ Yes (and built-in with Stream & Listeners)
Useful in Flutter?✅ Absolutely — it’s fundamental

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Lên đầu trang