TLDR: When following clean architecture, when should a reusable piece of functionality be reused across different apps via a module vs a template, and how does one decide on the interface of a module?
Background
I'm currently writing some packages (for personal use when freelancing) for common functionality that can be reused across multiple Flutter apps and wondering what's a good way to organise them. With my apps I follow the clean architecture guidelines, splitting an app by features, with each feature consisting of data, domain and presentation layers:
|--> lib/
|
|--> feature_a/
| |
| |--> data/
| | |
| | |--> data_sources/
| | |
| | |--> repository_implementations/
| | |
| |--> domain/
| | |
| | |--> repository_contracts/
| | |
| | |--> entities/
| | |
| | |--> use_cases/
| | |
| |--> presentation/
| | |
| | |--> blocs/
| | |
| | |--> screens/
| | |
| | |--> widgets/
| | |
|--> feature_b
| |
| |--> ...
Example
If we take the user authentication feature, for example, I know that:
- The entire domain layer, as well as the bloc, will be the same across most apps (email and password validation, authentication/login blocs, etc.)
- The data layer will change depending on the backend/database
- The screens/widgets will change with different UI's
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".
Questions
- What is the standard practice for deciding on the boundary of a module? i.e. is this approach of using the "highest common layer" (bloc in the authentication example) the way to go?
- When should a reusable piece of functionality be extracted as a template vs a module (is my example even a good candidate for a module, should it be a template instead)?
Thanks for your help
Aucun commentaire:
Enregistrer un commentaire