Learn

Presenter as the adaptation boundary

Convert complete business input into presentation-ready data, public feature actions, and guarded transient effects.

v0.1.0-dev.1Intermediate

Presenter as the adaptation boundary

Presenter stands between Model and View. Its central job is not forwarding state but assigning presentation meaning.

dart
final class CounterPresenter extends Presenter<
    CounterModel,
    CounterViewState,
    CounterEffect,
    CounterEnvironment> {
  @override
  CounterViewState buildViewState(CounterEnvironment environment) {
    return CounterViewState(
      valueLabel: environment.formatNumber(model.value),
      canIncrement: model.value < 100,
    );
  }

  void increment() {
    if (model.value >= 100) {
      emitEffect(const CounterLimitReached());
      return;
    }
    model.increment();
  }
}

What Presenter should do

  • combine several business snapshots into one screen state;
  • convert domain values into localized or formatted text;
  • derive visibility, enabled state, loading, empty, and error variants;
  • expose named feature actions to View;
  • compare meaningful Model transitions before emitting an effect;
  • keep small resettable presentation choices when appropriate.

What Presenter should not do

  • own the UseCase, Repository, or application manager behind Model;
  • store BuildContext for later use;
  • execute side effects from buildViewState;
  • retain business truth that must outlive the View;
  • expose Model directly to child widgets.

Presentation-local state

A selected local tab or expanded details panel can live in Presenter when resetting it with the feature is acceptable. After changing such state, call invalidateView(). If resetting would violate product behavior, the value belongs in a longer-lived business boundary and therefore enters Presenter through Model.

ARKTELOS

Purpose-built engineering systems for software that has to hold.