S.I.A: Architecture
Simple Intuitive Architecture
[UPDATE w.i.p] :
L’article est en cours d’update, mais les derniers ajustements de l’architecture sont déjà disponibles sur YouTube: https://youtu.be/eaZO3tD8xeo
# Introduction.
L’architecture que je vais vous présenter a été créée pour répondre à trois problématiques:
- Permettre aux développeurs séniors de ne pas être limité, ou perdre du temps à cause de l’architecture.
- Permettre aux développeurs juniors d’utiliser facilement une clean archi.
- Permettre à un développeur qui ne connaît pas le projet de pouvoir trouver rapidement ce qu’il cherche.
Ces problématiques ont été définies via mon expérience personnelle et donc des problématiques que j’ai pu rencontrer, mais surtout via des discussions que j’ai pu avoir lors d’entretiens avec d’autres développeurs sur leurs expériences quant à l’utilisation de VIPER, MVVM, MVC …
Stack technique: Swift + SwiftUI.
# La base de l’architecture
L’architecture est composée de 4 dossiers, nous allons introduire un par un ces dossiers par une présentation simple et rapide, puis nous allons voir comment convertir une maquette d’un designer vers du code avec SIA comme architecture.
## Tools
On commence basique avec “La boîte à outils du développeur” (aka Tools), la majorité de vos fichiers dans “Tools” vont être des extensions de classe déjà existante dans le but d’y rajouter des fonctionnalités.
Ou de nouvelles classes génériques utilisables partout dans l’application, plusieurs conseils pour garder un dossier Tools propre et clair :
- Vous avez développé un “Tool” conséquent faisant plusieurs fichiers, pourquoi ne pas en faire un Pod ? 🙂
- N’hésitez pas à créer une class “Tools” dans le but d’y regrouper des “Tool” qui ne sont pas une extension de classe.
## Apps
Le dossier App regroupe les vues utilisateur, par exemple :
- La “Home”
- La page “Mon compte”
- …
Ces vues vont se construire via les différents composants que nous allons créer dans le dossier “Data”.
Un fichier présent dans “App” se nomme comme-ci : “App” + “Nom de la vue”. Le but étant d’éviter les conflits avec un nom déjà existant.
La création de la classe se fait à l’intérieur de la classe “App” afin de scoper celle-ci dans “App”.
“App” correspond à votre `@main`, dans l’exemple ci-dessous :
## Ressource
Le dossier ressource reste classique comme dans beaucoup d’architecture. Dans celui-ci nous allons retrouver nos couleurs, nos images etc.
Un article est en cours d’écriture pour expliquer comment intégrer un DesignSytem de manière simple et rapide dans une application iOS, pensez donc à me follow pour recevoir la notification 🎉 #ad, petit teasing :
## Data
Ce dossier est au centre de SIA, il regroupe les modèles de donnée ainsi que les différentes façons de les afficher.
Prenons un exemple :
Pour la gestion de “Todo”, nous avons donc un dossier “Todo” dans “Data” afin de regrouper nos classes, à l’intérieur de celui-ci un dossier “Model” va être rempli avec les différents modèles concernant “Todo” dans notre cas un seul.
⚠️ Warning: Séparez bien vos modèles, si dans votre modèles “Todo” vous avez “var author: User”, le modèle “User” ne doit pas être dans le dossier “Data/Todo/Model” il doit être dans son propre dossier “Data/User/Model” car User va disposer de ses différentes façons de s’afficher.
Reprenons notre exemple, nous allons créer les différentes possibilités d’afficher un “Todo”, dans notre cas :
- Une liste — TodoList.swift
- Une cellule — TodoRow.swift
Ces deux méthodes d’affichage (la classe Row et List) étendent de “Todo” :
Règle importante :
Le dossier “Data” à pour but unique la gestion de la donnée et ses différents formats d’affichage. Par exemple, le composant “Todo.List” ne doit pas faire de call API pour récupérer la liste des todos ce n’est pas son rôle, il reçoit un tableau de “Todo” en entrée et l’affiche sous forme de List uniquement.
Le call API va être fait via un composant de “App” donc une vue utilisateur par exemple : “App.MyTodos” va effectuer un call Api pour récupérer les todos de l’utilisateur et utilisera le composant “Todo.List” pour les afficher.
Cette règle est importante car elle permet de rendre totalement indépendant le composant de la vue qui l’utilise, donc si demain “Todo.Row” vient à changer d’UI, les différentes vues utilisateurs qui l’utilisent vont avoir la nouvelle UI sans aucune modification de code. Et bien entendu l’inversement s’entend, avec une vue qui viendrait à changer par exemple changer l’ordre de deux composant.
# Diviser pour mieux régner.
Comme nous l’avons vu, l’architecture repose sur une utilisation intelligente des scopes, ce qui permet de structurer de manière simple et intuitive les différentes parties du code, dans le but de respecter nos problématiques de départ.
Nous allons donc voir comment convertir un design.
Pour commencer nous avons donc une page d’accueil qui affiche un titre avec une liste de todo, avec ce que nous avons vue précédemment voici comment lire la maquette :
Donc une partie “Data” qui va être composée par notre modèle “Todo” celui-ci pouvant s’afficher dans une liste, nous allons au préalable créer une “Row” afin d’avoir un code plus propre, la liste utilisera cette Row.
Nous créons notre fichier d’API. Comme expliqué précédemment le composant (“Todo.x”) n’utilisera pas de call Api, mais plusieurs vues (“App.x”) peuvent en avoir besoin donc pour garder une cohérence les routes d’API qui concerne un modèle sont rajoutées dans le dossier “Data” de ce modèle.
Dans la partie “App” notre vue “Home” va s’occuper :
- De récupérer les “Todos”
- D’afficher le titre de la vue
- Puis elle utilisera le composant “Todo.List()” pour afficher les todos.
# Testez-vous.
Avant de résumer SIA et de vous partager mes retours, testons-nous, avec ces informations :
Un product owner vous demande de modifier l’affichage d’aperçu d’un jeu, il souhaite rajouter un shadow sur l’image et mettre le texte par-dessus celui-ci. Pensez-vous pouvoir localiser le dossier contenant le fichier à modifier ?
Si oui, nous avons correctement répondu à l’une de nos problématiques de départ.
Permettre à un développeur qui ne connaît pas le projet de pouvoir trouver rapidement ce qu’il cherche.
# Retour d’expérience
SIA est en place chez Prisma Media, depuis bientôt 2 ans, l’architecture a été intégrée de façon progressive par-dessus une architecture existante via l’ajout des dossiers “Tools”, “App”, “Ressource” et “Data” sans grande difficulté. Puis nous avons profité de chaque évolution/refonte des parties de l’application pour migrer les fichiers dans leurs dossiers correspondants.
L’architecture a subi quelques modifications à ses débuts, mais suite à ses premiers mois de mise en place et d’ajustement, l’architecture a su répondre à notre besoin et à nos attentes. Le projet est structuré, lisible, et simple de compréhension, l’utilisation de SIA n’augmente pas le temps de réalisation d’un ticket, il n’y a pas besoin de créer 50 dossiers / fichiers en amont. La réutilisation des composants est simple et rapide grâce à l’auto-complétion, MonModèle + MonFormat = “Todo.List()” / “User.Row()” …
SIA se veut agile, l’architecture peut s’adapter à votre besoin il n’y a pas de règle absolue, gardez bien à l’esprit de correctement scoper vos parties et l’auto-complétion vous simplifiera grandement la tâche.
# Conclusion
En conclusion de ces années d’utilisations, SIA nous permet d’avoir une architecture simple et claire d’utilisation avec les avantages de la clean archi sans la lourdeur que celles-ci peuvent engendrer.
Les nouveaux développeurs se repèrent rapidement dès leur arriver dans le projet sans avoir besoin d’un accompagnement important.
SIA peut être utilisé aussi bien pour structurer une application, qu’un pod, ce qui permet de garder une cohérence dans nos projets.
MERCI !
N’hésitez pas à me faire vos retours en commentaire, en espérant que SIA réponde à vos attentes.
Projet d’exemple : https://github.com/joey-barbier/SIA
Portfolio / Me contacter : https://www.joeybarbier.com/
PS: Une partie 2 viendra compléter l’utilisation de SIA, avec pour but de détailler la transition d’une application simple (comme dans notre exemple) qui grandirait vers une application volumineuse avec différentes parties distinctes.
Par exemple une application contenant uniquement des articles qui se voit rajouter une partie vidéo, puis une partie podcast. SIA nous permet de gérer très facilement ce cas de figure même avec des complexités comme par exemple, deux modèles “User” diffèrent entre la partie article et la partie podcast.