Dart: доступ к переменным, объединяющим классы

#flutter #dart

#flutter #dart

Вопрос:

У меня есть очень большой класс под названием DatabaseService , который извлекает, кэширует и обновляет различные потоки данных. Сейчас я пытаюсь разделить каждый логический блок данных на отдельные файлы, чтобы упростить управление. Тем не менее, я хотел бы сохранить все методы и потоки доступными, предоставив только один DatabaseService файл.

В моем DatabaseService есть эти различные группы методов и потоков данных, которые я разделяю на отдельные файлы:

  • Пользователи
  • Подача
  • Истории
  • Комментарии

Сложность заключается в том, что каждая группа данных зависит от потоков из других групп данных. Например, для комментариев требуется лента историй и так далее: Комментарии < истории < лента < пользователь

Моя первая итерация выглядела так:

 class DatabaseService {
  // Here, i expose the various streams from each subclass
  Stream<User> userStream = UserService.instance.userStream;
  Stream<Feed> feedStream = FeedService.instance.feedStream;
  Stream<Stories> storiesStream = StoriesService.instance.storiesStream;
  Stream<Comments> commentsStream = CommentsService.instance.commentsStream;
  ...

  DatabaseService() {
  }
  

Все быстро становится беспорядочным, когда мне приходится передавать данные в каждую вспомогательную службу и предоставлять несколько методов, или если мне нужно получить доступ к методам друг от друга.

Я изучил возможность использования mixins, которые выглядят великолепно, но я не могу получить доступ к потокам из одного подкласса в другой.

Есть ли лучший способ сделать это?

Ответ №1:

Хитрость заключается в создании базового абстрактного класса, в котором излагаются схемы для класса. Затем пусть каждый из подклассов реализует базовый класс, чтобы они знали о свойствах каждого другого класса в каждом из них. Наконец, DatabaseService реализует базовый класс и использует каждый из подклассов в качестве миксинов.

Смотрите ниже для примера:

Базовая база данных:

 
abstract class BaseDatabase {
  final firestore = FirestoreService.instance;
  final functions = FunctionsService.instance;

  ValueStream<User> userStream;
  Future<void> setUser(User user);

  Stream<Feed> feedStream;
  Stream<Story> storiesStream;
  Stream<List<Comment>> commentsStream;
  Stream<Location> locationStream(String locationId);
}
  

DatabaseService:

 part 'parts/feed.dart';

class DatabaseService extends BaseDatabase
    with
        UserService,
        LocationService,
        FeedService,
        CommentsService,
        ... {

  DatabaseService({authService}) {
    // Any other required initialization code here, for example something like this.
    authService.uid().listen((uid) => userId.add(uid));
  }
}
  

FeedService:

 part of '../database_service.dart';

mixin FeedService implements BaseDatabase {
  ValueStream<Feed> get feedStream => _getFeedStream().shareValue();

  Stream<Feed> _getFeedStream() => 
    // userStream is from the UserService.. Winning!
    userStream
      .distinct((oldUser, newUser) => oldUser.id == newUser.id)
      .switchMap((user) => firestore.get(...)
        .where((feeds) => feeds.length > 0)
        .map((feeds) => feeds[0]));