DEV Community

Cover image for đŸ‡«đŸ‡· La seule architecture qui compte
Nicolas Verinaud
Nicolas Verinaud

Posted on • Originally published at academie.ryfacto.fr on

đŸ‡«đŸ‡· La seule architecture qui compte

Ah, l’architecture d’une app iOS.

Vaste sujet qui me prĂ©occupe depuis que j’ai commencĂ© Ă  crĂ©er des apps iOS en 2010 (sortie du premier iPad, de l’iPhone 4 et d’iOS 4 !).

À chaque nouvelle app se pose cette question fatidique : quelle archi mettre en place ?

Aprùs tout, c’est un choix important, non ? Une fois l’architecture choisie, impossible de revenir en arriùre, n’est-ce pas ?

Mais dites-moi, c’est quoi une architecture ?

Architecture : définition

Prenons la définition du Larousse :

Organisation des divers Ă©lĂ©ments constitutifs d’un systĂšme informatique, en vue d’optimiser la conception de l’ensemble pour un usage dĂ©terminĂ©.

Il y a la notion d’ organisation ; il s’agit là d’organiser son code, ses modules, ses frameworks.

L’objectif est d’ optimiser la conception de l’ensemble ; il faut prendre du recul sur tout son code afin de l’optimiser.

Dans le but de rĂ©pondre Ă  un usage dĂ©terminĂ© ; cette notion d’usage, je l’interprĂšte d’un point de vue fonctionnel.

Maintenant que nous sommes d’accord sur la dĂ©finition ; quelles sont les caractĂ©ristiques d’une bonne architecture ?

Une bonne architecture

Je vais reprendre chacune des notions et tenter de déterminer les caractéristiques que je juge en adéquation avec la définition.

Pour rappel, il s’agit de limiter la rĂ©flexion au code d’une app iOS. (MĂȘme si, en rĂ©alitĂ©, cette rĂ©flexion est applicable Ă  tous logiciels.)

Organisation

Comment déterminer que le code de mon app iOS est bien organisé?

Primo, je trouve rapidement ce que je cherche.

Ex: je dois modifier l’écran de connexion, il doit bien exister un LoginViewController ou quelque chose comme ça.

Deuxio, je ne me perds pas en cours de route.

Contre-Ex: le LoginViewController fait quoi exactement ? Dans viewDidLoad : il configure des singletons (wtf?), modifie des contraintes (wtf??), fait un appel serveur (wtf???) ; il appelle des méthodes sur une super classe pour
je suis perdu je ne comprends plus rien !

Tertio, les dépendances ne partent pas dans tous les sens.

Contre-Ex: LoginViewController dépend de ClientAPI qui dépend de Configuration qui dépend de ClientAPI, wtf?

Optimiser la conception de l’ensemble

Comment déterminer que la conception est optimisée ?

Primo, je comprends facilement ce que le code fait.

Ex: LoginViewController a une méthode onLoginButtonTapped() qui appelle behavior.login().

Contre-Ex: LoginViewController a une mĂ©thode buttonTapped(_ sender: NSObject) qui teste si sender == button1 et qui fait plein de trucs sur 200 lignes avec un niveau d’imbrication au-delĂ  de toute raison et problablement un appel API cachĂ© au milieu ?

Deuxio, je retrouve les termes métiers dans le code.

Ex: quand je parle avec les utilisateurs et utilisatrices, ils Ă©voquent des Recettes et des IngrĂ©dients ; dans le code j’ai bien les notions de Recipe et d’Ingredient.

Tertio, j’arrive à changer facilement le code.

Contre-Ex: je modifie le login pour amĂ©liorer l’expĂ©rience utilisateur, je livre, et j’ai 36 nouveaux bugs Ă  des endroits improbables, whaaaat?

Un usage déterminé

Comment déterminer que la conception répond à un usage précis ?

Primo, il n’y a pas de code au cas oĂč.

Contre-Ex: je dois afficher des informations textuelles dans la v1. Je crée un InformationsBuilder qui accepte une dépendance implémentant le protocole InformationsStrategy et je crée une classe TextualInformationsStrategy qui implémente ce protocole.

Autre contre-ex: je vais crĂ©er une DSL de configuration de style, au cas oĂč je dois changer le thĂšme de l’app un jour.

Deuxio, il n’y a vraiment pas de code au cas oĂč !

Il m’est dĂ©jĂ  arrivĂ© de complexifier le code en essayant d’anticiper les besoins. C’est tentant et motivant de crĂ©er du code rĂ©utilisable. Mais dans 95% des cas c’est too much.

Mieux vaut dupliquer pour trouver la bonne abstraction que créer une mauvaise abstraction.

Je préfÚre dupliquer une ou deux fois, puis prendre du recul pour trouver comment factoriser le code, afin de créer des abstractions qui ont une réelle utilité et un véritable sens.

Une bonne conception

Une bonne architecture veut donc avant tout dire une bonne conception.

Une bonne conception respecte les critĂšres que j’ai listĂ©s ci-dessus et que je rappelle ici :

  • je trouve rapidement ce que je cherche,
  • je ne me perds pas en cours de route,
  • les dĂ©pendances ne partent pas dans tous les sens,
  • je comprends facilement ce que le code fait,
  • je retrouve les termes mĂ©tiers dans le code,
  • j’arrive Ă  changer facilement le code,
  • il n’y a pas de code au cas oĂč,
  • le code rĂ©pond Ă  un usage dĂ©terminĂ©.

Je ne vais pas vous le cacher, avoir une architecture qui remplit tous ces critĂšres est trĂšs difficile.

Il faut dĂ©jĂ  rĂ©ussir Ă  bien comprendre le besoin, Ă  dĂ©terminer prĂ©cisĂ©ment l’usage.

Il ne faut pas anticiper des demandes qui n’arriveront peut-ĂȘtre jamais.

Il faut rendre son code compréhensible par les autres humains qui vont le lire (et nous ne sommes pas tous égaux à ce niveau).

Il faut faire face aux particularitĂ©s des frameworks et librairies qu’on utilise.

Autant vous dire qu’avoir juste du premier coup relùve du miracle !

Faire Ă©merger la conception

Mais si je n’arrive pas Ă  avoir juste du premier coup
cela veut dire que je vais devoir changer ma conception en cours de route, la faire Ă©voluer ?

Exactement ! C’est ce que j’appelle faire Ă©merger la conception.

Oh ! Et du coup faire émerger la conception revient à créer


Une architecture Ă©mergente !

Je pars de deux hypothĂšses pour justifier le fait de faire Ă©merger l’architecture, plutĂŽt que de la figer dans le marbre Ă  l’avance.

  1. Il est impossible d’imaginer la bonne conception du premier coup.
  2. Le besoin change.

J’ai dĂ©jĂ  dĂ©taillĂ© le premier point ci-dessus, passons au second.

Le besoin change

Si seulement les utilisateurs, utilisatrices, clientes & clients arrĂȘtaient de changer tout le temps d’avis ! Cela serait beaucoup plus simple ! Nous aurions un cahier des charges figĂ© et des spĂ©cifications fonctionnelles figĂ©es. Il nous serait alors si simple de concevoir une app qui rĂ©ponde exactement Ă  ce qui est demandĂ©. Nous pourrions prendre le temps de bien concevoir, de faire de beaux diagrammes. Puis nous livrerions une app bien conçue et nous passerions Ă  la suivante.

Le rĂȘve quoi !

Vraiment ?

Nous savons que ce n’est jamais le cas. Qui a dĂ©jĂ  vĂ©cu cette situation, honnĂȘtement ?

Le besoin change !

Pourquoi change-t-il ?

Car crĂ©er un logiciel est principalement un travail de communication, de comprĂ©hension et d’empathie.

Entre ce que l’utilisateur a en tĂȘte, ce qu’il explique, ce que la dĂ©veloppeuse comprend et ce qu’elle exprime par code ; les risques de mauvaise interprĂ©tation sont lĂ©gions ! (Ajoutez quelques intermĂ©diaires entre les deux personnes et vous multiplierez ces risques. Coucou les Product Owner & Proxy Product Owner & Proxy Proxy Proxy
)

Ce n’est pas forcĂ©ment le besoin rĂ©el qui change, c’est notre comprĂ©hension qui Ă©volue ! Il nous arrive (souvent) de mal comprendre le besoin rĂ©el. Au fur et Ă  mesure que nous crĂ©ons et livrons le logiciel, nous apprenons des feedbacks ! Et nous devons reflĂ©ter cette comprĂ©hension dans notre code.

Conclusion

Bonne architecture veut dire bonne conception.

Avoir une conception juste du premier coup est impossible car le besoin change, notre compréhension de celui-ci change.

Il faut donc ĂȘtre capable de faire Ă©voluer cette conception, de la faire Ă©merger.

Pour cela, nous devons nous assurer que nous ne cassons rien au passage.

Et pour ne rien casser
on fait comment ?

Je vous en parle dans le prochain article. 😉

Pour ne pas le manquer, inscrivez-vous Ă  ma newsletter !

Top comments (0)