Каков наилучший способ модульного использования повторно используемых функций в приложениях Flutter?

#flutter #authentication #design-patterns #interface #architecture

Вопрос:

TLDR: При соблюдении чистой архитектуры, когда следует повторно использовать повторно используемую функциональность в разных приложениях с помощью модуля или шаблона и как выбрать интерфейс модуля?

Фон

В настоящее время я пишу несколько пакетов (для личного использования во фрилансе) для общих функций, которые могут быть повторно использованы в нескольких приложениях Flutter, и мне интересно, как их правильно организовать. В своих приложениях я следую рекомендациям по чистой архитектуре, разделяя приложение по функциям, причем каждая функция состоит из слоев данных, домена и представления:

 |--> lib/
      |
      |--> feature_a/
      |       |
      |       |--> data/
      |       |      |
      |       |      |--> data_sources/
      |       |      |
      |       |      |--> repository_implementations/
      |       |      |
      |       |--> domain/
      |       |      |
      |       |      |--> repository_contracts/
      |       |      |
      |       |      |--> entities/
      |       |      |
      |       |      |--> use_cases/
      |       |      |
      |       |--> presentation/
      |       |      |
      |       |      |--> blocs/
      |       |      |
      |       |      |--> screens/
      |       |      |
      |       |      |--> widgets/
      |       |      |
      |--> feature_b
      |       |
      |       |--> ...

 

Пример

Если мы возьмем функцию аутентификации пользователя, например, я знаю, что:

  • Весь доменный уровень, а также блок будут одинаковыми для большинства приложений (проверка электронной почты и пароля, блоки аутентификации/входа в систему и т.д.).
  • Уровень данных будет меняться в зависимости от серверной части/базы данных (разные поставщики = разные вызовы)
  • Экраны/виджеты будут меняться в зависимости от пользовательского интерфейса (разные приложения будут иметь разные страницы входа и регистрации).

Current Approach

My thinking is to write something like a single backend-agnostic «core_auth_kit» package, which contains the domain and bloc, and one package for each backend service I might use, e.g. «firebase_auth_kit», «mongodb_auth_kit», etc. Each backend-specific package will use the «core_auth_kit» as the outward-facing interface.

Here’s how I plan on using this. If I’m writing a simple Firebase Flutter app, I will simply import the «firebase_auth_kit» package, and instantiate its auth_bloc at the root of the app inside a MultiBlocProvider, showing the login page if the state is «unauthenticated» and the home page if it’s «authenticated».
diagram of package structure

Questions

  1. Какова стандартная практика для определения границы модуля? т. е. является ли этот подход с использованием «самого высокого общего уровня» (блок в примере аутентификации) правильным?
  2. Когда следует извлекать повторно используемую часть функциональности в качестве шаблона или модуля (является ли мой пример хорошим кандидатом на модуль или вместо этого он должен быть шаблоном)?