Irbisa · Шпаргалка
Паттерны проектирования
Singleton, Factory, Observer, Builder, Strategy, Command во Flutter
Этот
Sessionзадуман как singleton, но токен, сохранённый при логине, на следующем экране равенnull. Почему?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}Какие паттерны GoF встречаются в самом Flutter и в типичном Flutter-приложении?
Как реализовать Singleton в Dart и какие у него недостатки?
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>[];…Зачем нужен паттерн Repository и как он позволяет переключаться между локальной базой и удалённым API?
abstract interface class WeatherRepository { Future<Weather> getWeather(String city);} class WeatherRepositoryImpl implements WeatherRepository { WeatherRepositoryImpl(this._api, this._db);…Найдите баг: включение фильтра «Только со скидкой» в корзине уменьшает и итоговую сумму заказа.
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;}Как делать внедрение зависимостей во Flutter (
get_it,injectable, Riverpod или обычный constructor injection) и в чём их компромиссы?// 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);…Найдите баг: экран входа работает в первый раз, но при следующем заходе нажатие Sign in бросает
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(), );}Что такое паттерн Facade и чем он отличается от Repository?
Как применить паттерн Adapter, чтобы обернуть несогласованный сторонний API?
// Your contractabstract interface class Analytics { Future<void> logEvent(String name, Map<String, Object> params);} // Vendor SDK with its own shape (simplified)…Как реализовать паттерн Decorator в Dart и когда mixin или extension покрывают ту же задачу?
abstract interface class UserRepository { Future<User> byId(String id);} class LoggingUserRepository implements UserRepository { LoggingUserRepository(this._inner);…Два виджета одновременно вызывают
byId('42')через этот кеширующий декоратор. Сколько запросов уйдёт в сеть и как это исправить?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; }}Функции в Dart являются объектами первого класса, так когда всё же писать интерфейс Strategy вместо колбэка?
// 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…Как реализовать паттерн Command с поддержкой undo/redo?
abstract interface class Command { void execute(); void undo();}class History { final _undo = <Command>[];…Именованные аргументы, каскады и copyWith уже закрывают почти весь GoF-паттерн Builder. Когда в Dart всё ещё стоит писать настоящий класс-билдер?
Что такое паттерн Template Method и как его использует жизненный цикл
Stateво Flutter?Как паттерн Observer связан с
ChangeNotifier,Streamи BLoC?Память растёт каждый раз, когда пользователь открывает и закрывает экран, и все цепочки удержания упираются в глобальный
ChangeNotifier. Что пошло не так?class _ProfileState extends State<Profile> { late final AuthNotifier _auth; @override void initState() { super.initState();…Как паттерн State соотносится с sealed-классами Dart 3?
// State pattern: behaviour and transitions live in the state objectsabstract interface class PlayerState { PlayerState onTap();}class Playing implements PlayerState { @override…API ленты помечает каждый элемент полем
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),…Как собрать композируемую цепочку middleware в Dart и когда это лучше набора if-ов?
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));…Как выпустить один API с разными реализациями под мобильные платформы и веб, если
dart:ioв браузере бросает исключение, аpackage:webне компилируется на мобильных?// 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';…Вы рендерите AST документа в виджеты, и из того же дерева нужен ещё простой текст для поиска: Visitor или sealed-класс с двумя switch?
sealed class Node {} final class Heading extends Node { Heading(this.level, this.text); final int level; final String text;…