class: title smokescreen no-footer shelf background-image: url(/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/intro.jpg) # Flutter ## Quelle architecture après mon POC ? --- class: col-2 # A mon propos ![John Thiriet Picture](/assets/images/bio-photo.jpg) @johnthiriet Mobile lead engineer @ Edenred _Epitech Promotion 2019_ - Développement d'application mobiles *(iOS, Android and Windows)* et .NET - 12 ans d'expérience professionnelle - Ancien MVP Microsoft et Xamarin - Speaker (Techdays, Microsoft Experiences, Xamarin Day, Meetups...) - Auteur d'articles dans la presse spécialisée et en ligne --- class: col-2 # A propos de mon employeur ![Edenred Logo](/assets/images/presentations/edenred.png) **Enrich connections. For good.** _[Rapport intégré 2020-2021](https://www.edenred.com/sites/rapport-2020/files/2021-05/Edenred-Rapport-Integre-2020-2021-FR.pdf)_ - 10000 employés dans 46 pays - \> 850000 entreprises clientes - \> 50 millions d'utilisateurs - \> 2 millions de commerçants partenaires - Près de 30 Mds€ de volume d’affaires dont 86 % est digital - \> 2,5 Mds de transactions --- # Agenda Flutter est devenue une technologie très populaire bien que jeune. Dans cette petite présentation nous ferons un récapitulatif de ce qu'est Flutter et de sa promesse. Nous verrons ensuite comment s'y prendre avoir une bonne architecture logicielle en Flutter. 1. Flutter 2. Architecture (SOLID, IOC, YAGNI, DRY ....) 3. Demo ??? Flutter est devenue une technologie très populaire bien que jeune. Cette jeunesse nous force à faire des choix qui n'ont pas tous été éprouvés. Mais est-ce bien vrai ? --- class: title, fogscreen, no-footer background-image: url(/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/hummingbird.jpg) # Flutter --- class: compact # Flutter > Flutter is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, desktop, and embedded devices from a single codebase. - Rapidité de développement - Flexibilité et expressivité de l'UI - Performance native ```dart class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar(title: const Text('Welcome to Flutter')), body: const Center(child: Text('Hello World')), ), ); } } ``` --- class: roomy # Quelle gestion des états pour mon application ? -- - Provider -- - Riverpod -- - Redux -- - BLoC -- - GetIt -- - GetX [https://docs.flutter.dev/development/data-and-backend/state-mgmt/options](https://docs.flutter.dev/development/data-and-backend/state-mgmt/options) --- # Provider ```dart void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => CartModel()), Provider(create: (context) => SomeOtherClass()), ], child: const MyApp(), ... ``` ```dart return Consumer
( builder: (context, cart, child) { return Text("Total price: ${cart.totalPrice}"); ... ``` --- # Bloc - Cubit ```dart return Consumer
( builder: (context, cart, child) { return Text("Total price: ${cart.totalPrice}"); ... ``` ```dart BlocListener
( listener: (context, state) { ... ``` ```dart BlocListener
( listener: (context, state) { ... ``` --- class: img-caption ![It does not matter](/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/ignore.jpg) Rien de tout ceci n'est vraiment important. --- class: roomy # Architecture en Flutter Flutter et Dart permettent une grand souplesse. Qui dit souplesse dit souvent raccourci dans les implémentations. Une bonne architecture est donc indispensable ! --- class: title, fogscreen, no-footer background-image: url(/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/architecture.jpg) # Architecture --- class: compact # Architecte > A software architect is a software development expert who makes high-level design choices and tries to enforce technical standards, including software coding standards, tools, and platforms. ![Architect](/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/thinking_architect.jpg# w-33pct db fr mr-4) - L'architecte logiciel a besoin d'avoir une vision globale du système à concevoir ou à maintenir. - Il est souvent le seul à avoir la capacité d'anticiper, de détecter et résoudre les problèmes résultant de l'interaction entre les différentes parties de ce système. - Il peut s'agir par exemple de problèmes d'interopérabilité, de productivité, d'intégration ou de performance. - Il travaille souvent avec une vision abstraite et synthétique du système considéré. *Wikipedia* --- # Architecture L'architecture logicielle est l'organisation d'un système. Elle inclue : - tous les composants - leurs interactions - l'environnement dans lequel elles s'opèrent - les principes utilisés pour designer le logiciel Dans beaucoup de cas, elle inclue également l'évolution du logiciel dans le futur. > Architecture n'est pas coding guideline --- class: col-2 # Pourquoi parler d'architecture ? Généralement, on ne se préoccupe pas trop du fonctionnement du flux de données, d'écrire des couches de gestion de données séparées, d'utiliser la programmation orientée objet, du test ou de l'extensibilité des fonctionnalités. > Tout ce que l'on souhaite, c'est publier notre application le plus rapidement possible. Mais tout finit par se payer plus tard. ![Technical debt](/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/technical_debt.svg) --- # Une bonne architecture C'est donc: - Performance - Productivité - Maintenabilité - Rapidité d'onboarding - Testabilité - Facilité de lecture Indispensable pour les gros projets avec pleins de features, pleins de développeurs en parallèle etc... --- class: img-caption # Clean architecture ![Uncle Bob clean architecture diagram](/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/uncle_bob_clean_architecture.png) --- class: compact # Structure des dossiers ![](/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/folder_structure.png# w-6-12th db mr-4) *[https://devmuaz.medium.com/flutter-clean-architecture-series-part-1-d2d4c2e75c47](https://devmuaz.medium.com/flutter-clean-architecture-series-part-1-d2d4c2e75c47)* --- class: roomy # Clean architecture Trois couches principales existent : - Data : Logique de communication avec la base de données, les APIs etc... Cela inclut les `repositories` et les `data sources`. -- - Domain : Logique métier. Contient les `models` et les `use cases`. -- - Presentation : UI. Contient les `views`, `presenters`, `viewmodels`, `blocs`, `cubits ` ... ??? - Data sources implement logic of data access from different sources (such as network, database, disk etc). - Repositories contain queries and mutations for a specific data model and can decide from which data source gets data (request it from network or get from cache for example). - Models declare data format. - Use cases combine data from one or multiple repositories. - The Use case is a class where you extract the business logic out of your Presenter/ViewModel. - This makes the Presenter/ViewModel simpler because it only coordinates the view and calls Use case. - This approach helps to write testable, supportable code. - View is what users interact with and coordinated by Presenter / ViewModel which executes one or more Use Cases. - The Presentation Layer always depends on the Domain Layer. Data and Domain can depend on each other and it depends on the variant of implementation. --- # Data sources ```dart class UserApiSource { var client = http.Client(); Future
getUser(int userId) async { try { var response = client.get("https://johnthiriet.com/api/user/${id}") return User.fromJson(response.data); } catch (e) { throw NetworkException(); } } ``` > Les `data sources` implémentent la logique d'accès aux données (network, database, disk, etc...). --- # Repositories ```dart abstract class IMovieRepository { Future
> getLastestMovies(); } ``` ```dart class MovieRepository implements IMovieRepository { @override Future
> getLastestMovies() { // Use data source to get data } } ``` > Les `repositories` contiennent les requêtes et mutations sur un `model` spécifique et choisisent depuis quelle `data source` récupérer la donnée. ??? - Repositories in domain layer: They are abstract classes, or contracts, and define the properties and methods that our project will need in a specific feature. - Repositories in the data layer: These are the implementations of the contracts that we define in the domain layer. --- # Use cases ```dart class SignInUser { SignInUser(this._authRepo); final IAuthRepository _authRepo; Future
call(String email, String password) async { return await _authRepo.signIn(email, password); } } ``` > Les `use cases` combinent les données d'un ou plusieurs `repositories`. > C'est une classe dont le rôle est d'extraire la logique métier pour le presenter, viewmodel, bloc etc... ??? - The Use case is a class where you extract the business logic out of your Presenter/ViewModel. - This makes the Presenter/ViewModel simpler because it only coordinates the view and calls Use case. - This approach helps to write testable, supportable code. --- class: roomy # SOLID 1. Single Responsability Principle 2. Open-Closed Principle 3. Liskov Substitution Principle 4. Interface Segregation Principle 5. Dependency Inversion Principle ??? 1. Each class should solve only one problem. 2. Open for extension, meaning that the class’s behavior can be extended; and Closed for modification, meaning that the source code is set and cannot be changed. 3. This principle simply requires that every derived class should be substitutable for its parent class. 4. It’s better to have a lot of smaller interfaces than a few bigger ones. 5. Developers should “depend on abstractions, not on concretions.” --- # Dependency Inversion ou Injection ? `Dependency Injection` est une technique d'`Inversion of Control` pour fournir des objets (dépendences) a une classe typiquement en passant cette dépendence via : - Un constructeur - Une propriété publique - Un champs public `Dependency Inversion Principle` est une pratique la pratique d'architecture logicielle recommandant un découplage entre une classe et ses dépendences concrètes. --- # Dependency Injection ```dart @injectable class ServiceA {} @injectable class ServiceB { ServiceB(ServiceA serviceA); } ``` > Le package `injectable` permet de générer automatiquement le code d'injection. > Il utilise `get_it` comme conteneur d'IOC. ```shell flutter packages pub run build_runner watch ``` --- # Tests unitaires ```dart class FakeCat extends Fake implements Cat { @override bool? eatFood(String? food, {bool? hungry}) { print('Fake eat $food'); return true; } } ``` > Le package `mockito` permet de générer des mocks. --- class: compact # Test unitaires ```dart late Cat cat; setUp(() { // Create mock object. cat = MockCat(); }); test("Let's verify some behaviour!", () { // Stub a method before interacting with it. when(cat.sound()).thenReturn('Meow'); // Interact with the mock object. cat.sound(); // Verify the interaction. verify(cat.sound()); }); ``` > On voit ici l'utilisation de ces mocks dans les tests unitaires. --- class: img-right-full # Outils et bibliothèques ![library](/assets/images/presentations/epitech-alumni-flutter-quelle-architecture-apres-mon-poc/library.jpg) - retrofit - dio - flutter_bloc - provider - riverpod - equatable - dartz - get_it - injectable - lint - mockito - ... --- class: roomy col-2 # Clean architecture, quels impacts ? Inconvénients - Code boilerplate - Ne convient pas à tous les projets - Peut-être implémenté de différentes manières - Ralenti le début des développements Avantages - Abstraction par rapport aux outils et frameworks - Maintenables à long terme - Testabilité et extensibilité - Convient à de grosses équipes - Bien structuré --- class: title, fogscreen, no-footer background-image: url(/assets/images/presentations/introduction-to-maui-2021/conclusion.jpg) # Pour résumer --- class: col-2 # Pour résumer Architecturer une application Flutter n'est pas fondamentalement différent du reste. - Abstractions - Limitation des dépendences - Designs patterns - Etude du besoin - Domain Driven Design - Tests unitaires A la question, quelle architecture choisir mon pour application Flutter, la réponse doit être : Ça dépend ! - Projet one-shot ou projet long terme ? - Beaucoup de développeurs ou non ? - Beaucoup d'écrans ou non ? --- # Slides .qrcode.db.fr.w-40pct.ml-4[] Slides disponibles dans la section [présentation](/presentations/) de mon site. Vous pouvez aussi scanner ce QrCode pour un accès direct. @johnthiriet - [Twitter](https://twitter.com/JohnThiriet) - [LinkedIn](https://linkedin.com/in/JohnThiriet)