для простых и незацепленных компонентов, которые в приложении гарантированно будут синглтонами, я стал использовать статику. Упрощает синтаксис, не нужно постоянно извлекать объект из DI или писать .instance. Вот пример такого компонента - детектирует состояние сети путем периодического пинга сервера. Вопрос - насколько приемлемо использовать статику, какие грабли могут быть? Слышал, что статика - это зло, но до сих пор не понял почему. Спасибо.
import 'dart:async';
import 'package:get/get.dart';
import '/config/app_settings.dart';
import '/core/state/app_auth_state.dart';
import '/data/remote/ping_remote_client.dart';
class NetworkStatusObserver {
static bool _isConnected = true;
static bool _exit = false;
static final _streamController = StreamController<bool>.broadcast();
static late final _pingRemoteClient;
static bool get isOffline => !_isConnected;
static Stream<bool> get stream => _streamController.stream;
NetworkStatusObserver._();
static Future<void> init() async {
_pingRemoteClient = PingRemoteClient();
await _detect();
() async {
while (!_exit) {
await Future.delayed((_isConnected) ? AppSettings.pingIntervalOnline : AppSettings.pingIntervalOffline);
await _detect();
}
}();
}
static Future<void> _detect() async {
bool connected;
try {
final start = DateTime.now();
await _pingRemoteClient.ping();
final diff = DateTime.now().difference(start);
print('ping delay: $diff');
connected = true;
if (AppSettings.detectSlowNetwork &&
DateTime.now().difference(start) > Get.find<AppAuthState>().maxPingDelay.value) {
connected = false;
}
} catch (_) {
print('ping failed');
connected = false;
}
if (connected != _isConnected) {
_isConnected = connected;
_streamController.add(_isConnected);
}
}
// Если сетевая ошибка пришла по действию пользователя раньше, чем по пингу
static void forceTurnOffline() {
_isConnected = false;
_streamController.add(_isConnected);
}
static void dispose() {
_exit = true;
_streamController.close();
}
}
Будешь делать тесты - придется рефакторить.
Статику не замокаешь. Статика существует не в контексте объекта, а в контексте класса
https://stackoverflow.com/a/7084473
Ну, принимается. Хотя у нас нет автотестов и не будет.
Такие проекты или учебные, или потом будет попоболь и слезы.
Ты шутишь. У меня в проде одна социальная сеть и один корпоративный апп. Никаких автотестов, только интеграционные по экрану.
Для автотестов нужен двойной бюджет проекта и специальный тестировщик. Которых никогда не дают.
Спасибо за статью!
Обсуждают сегодня