Irbisa · Cheatsheet
Design Patterns
Singleton, Factory, Observer, Builder, Strategy, Command in Flutter
This
Sessionis meant to be a singleton, yet the token saved at login isnullon the next screen. Why?class Session { Session._(); static Session get instance => Session._(); String? token;} void onLoggedIn(String token) { Session.instance.token = token;} void onNextScreen() { print(Session.instance.token); // null}Which GoF design patterns do you see in Flutter itself and in a typical Flutter app?
How do you implement a Singleton in Dart, and what are its drawbacks?
class Analytics { Analytics._(); // nobody else can construct it static final Analytics instance = Analytics._(); // created on first read factory Analytics() => instance; // optional: Analytics() is the same object final _events = <String>[];…Why use the Repository pattern, and how does it let you switch between a local database and a remote API?
abstract interface class WeatherRepository { Future<Weather> getWeather(String city);} class WeatherRepositoryImpl implements WeatherRepository { WeatherRepositoryImpl(this._api, this._db);…Find the bug: switching on the cart's "On sale only" filter also lowers the checkout total.
class CartRepository { final _items = <CartItem>[]; List<CartItem> get items => _items; int get totalCents => _items.fold(0, (sum, i) => sum + i.priceCents * i.qty); void add(CartItem item) => _items.add(item);} // Cart screen, "On sale only" chipList<CartItem> visibleItems(CartRepository repo, {required bool onSaleOnly}) { final visible = repo.items; if (onSaleOnly) visible.removeWhere((i) => !i.onSale); return visible;}How do you do dependency injection in Flutter (
get_it,injectable, Riverpod or plain constructor injection), and what are the trade-offs?// The class itself: constructor injection, no container in sightclass LoginViewModel { LoginViewModel(this._auth); final AuthRepository _auth; Future<void> login(String email, String pass) => _auth.signIn(email, pass);…Find the bug: the login screen works the first time, but on the next visit tapping Sign in throws a
StateError.void setupLocator() { sl.registerLazySingleton<AuthRepository>(() => AuthRepositoryImpl(sl())); sl.registerLazySingleton<LoginBloc>(() => LoginBloc(sl()));} class LoginPage extends StatelessWidget { const LoginPage({super.key}); @override Widget build(BuildContext context) => BlocProvider( create: (_) => sl<LoginBloc>(), child: const LoginForm(), );}What is the Facade pattern, and how does it differ from a Repository?
How do you apply the Adapter pattern to wrap an inconsistent third-party API?
// Your contractabstract interface class Analytics { Future<void> logEvent(String name, Map<String, Object> params);} // Vendor SDK with its own shape (simplified)…How do you implement the Decorator pattern in Dart, and when do mixins or extensions cover the same need?
abstract interface class UserRepository { Future<User> byId(String id);} class LoggingUserRepository implements UserRepository { LoggingUserRepository(this._inner);…Two widgets call
byId('42')at the same moment through this caching decorator. How many network requests go out, and how do you fix it?class CachingUserRepository implements UserRepository { CachingUserRepository(this._inner); final UserRepository _inner; final _cache = <String, User>{}; @override Future<User> byId(String id) async { final hit = _cache[id]; if (hit != null) return hit; final user = await _inner.byId(id); _cache[id] = user; return user; }}Functions are first-class in Dart, so when do you still write a Strategy interface instead of passing a callback?
// A plain function is enough: one operation, no statetypedef PriceFormatter = String Function(int cents); // An interface earns its place: several operations, config and a nameabstract interface class RetryPolicy { String get name; // identity for logs and tests…How do you implement the Command pattern with undo/redo support?
abstract interface class Command { void execute(); void undo();}class History { final _undo = <Command>[];…Named arguments, cascades and copyWith already cover most of the GoF Builder, so when is a real builder class still worth writing in Dart?
What is the Template Method pattern, and how does Flutter's
Statelifecycle use it?How does the Observer pattern relate to
ChangeNotifier,Streamand BLoC?Memory grows each time users open and close a screen, and every retaining path ends at an app-wide
ChangeNotifier. What went wrong?class _ProfileState extends State<Profile> { late final AuthNotifier _auth; @override void initState() { super.initState();…How does the State pattern compare with Dart 3 sealed classes?
// State pattern: behaviour and transitions live in the state objectsabstract interface class PlayerState { PlayerState onTap();}class Playing implements PlayerState { @override…Your feed API tags each item with a
typeand new kinds ship every sprint. How do you parse it, and what does an old app do with an unknown type?sealed class FeedItem { const FeedItem(); // One factory owns the dispatch; map patterns also check the field types factory FeedItem.fromJson(Map<String, dynamic> json) => switch (json) { {'type': 'post', 'text': String text} => PostItem(text),…How would you build a composable middleware chain in Dart, and when is that better than a list of if-statements?
typedef Handler = Future<Response> Function(Request req);typedef Middleware = Handler Function(Handler next); // The first stage in the list becomes the outermost oneHandler pipeline(List<Middleware> stages, Handler endpoint) => stages.reversed.fold<Handler>(endpoint, (next, stage) => stage(next));…How do you ship one API with different implementations for mobile and web when
dart:iothrows in the browser andpackage:webdoes not compile on mobile?// secure_store.dart: the only file the app importsexport 'src/secure_store.dart';export 'src/create_store_stub.dart' if (dart.library.io) 'src/create_store_io.dart' if (dart.library.js_interop) 'src/create_store_web.dart';…You render a document AST to widgets and also need plain text out of the same tree for search: Visitor, or a sealed class with two switches?
sealed class Node {} final class Heading extends Node { Heading(this.level, this.text); final int level; final String text;…