Comment les choses évoluent : une introduction à la conception de logiciels évolutifs dans le monde réel

Dec 03 2022
L'intention derrière cet article est d'exposer certains principes fondamentaux de la conception de systèmes logiciels - en mettant davantage l'accent sur l'aspect conception. Il répond à une question, via un exemple concret, que de nombreux ingénieurs se posent : comment puis-je même commencer à concevoir un système ? J'ai constaté que trop de ressources en ligne se concentrent sur les outils et sur l'approche « se salir les mains ».

L'intention derrière cet article est d'exposer certains principes fondamentaux de la conception de systèmes logiciels - en mettant davantage l'accent sur l' aspect conception .

Il répond à une question, via un exemple concret, que de nombreux ingénieurs se posent : comment puis-je même commencer à concevoir un système ?

J'ai constaté que trop de ressources en ligne se concentrent sur les outils et sur l'approche « se salir les mains ».

Bien que la maîtrise des outils soit importante, nous sautons, plus souvent que nous ne l'admettons, la pièce centrale du puzzle ; la réflexion de haut niveau sur la façon dont les choses fonctionnent avant même que nous essayions de les coder dans nos soi-disant langages de programmation.

En son cœur, "l'art de la programmation est l'art d'organiser la complexité" (Farley, David. Génie logiciel moderne).

Organiser la complexité devrait venir avant de commencer à taper du code (ou peut-être même de penser aux systèmes informatiques du tout !).

Ainsi, nous plongerons dans un exemple de cas réel de la façon dont nous pouvons utiliser des concepts qui garantiront qu'une instance particulière de notre système sera capable de s'adapter et d'identifier ce que sont ces concepts.

Bouclez votre ceinture !

Permettez-moi de vous donner un peu de contexte sur Creator Now .

Au cœur de notre activité, nous devons gamifier les informations sur les chaînes YouTube des créateurs afin de leur offrir les meilleures expériences d'apprentissage et de croissance pour leur parcours de créateur.

Cela signifie que, pour chaque nouvel utilisateur enregistré, nous devons nous appuyer fortement sur l'API de YouTube pour extraire des informations sur la vie de leur créateur.

Nous voulons nous assurer que ces informations sont mises à jour aussi souvent que possible. Après tout, il ne sert à rien de maintenir un produit où l'élément d'information de base qui alimente l'expérience utilisateur est en retard par rapport à la réalité du « monde réel ».

Voici notre principal défi :

Comment pouvons-nous évoluer si nous devons compter sur une API tierce avec des limites qui échappent à notre contrôle ?

Tout d'abord, comprenons comment fonctionne l'API YouTube et où se situe réellement le problème en utilisant une analogie avec le monde réel.

Imaginez que l'API YouTube soit un grand bureau qui contient les données de toutes les chaînes et de tout ce qui concerne YouTube.

Chaque fois que quelqu'un sur Internet veut vérifier des informations sur un canal spécifique, il y va. En bref, ils doivent tous envoyer quelqu'un dans ce bâtiment pour demander cette information.

Le déroulement est assez simple : quelqu'un entre par la porte d'entrée. Ils présentent leurs lettres de créance au gardien. Une fois qu'ils sont autorisés à entrer, ils sont servis par un employé YouTube heureux :

  • Bonjour monsieur; quelle est l'info que tu désires?
  • Pouvez-vous s'il vous plaît vérifier les dernières informations sur la chaîne CatsAreAmazing ?
  • Bien sûr, laissez-moi vérifier nos fichiers ! <extrait les données du canal et en rend un rapport d'une page>
  • Merci, bon monsieur !
  • J'espère que les bureaux de YouTube sont plus récents que ça !

Mais YouTube a connu un nombre écrasant de personnes demandant des choses.

Étant donné que tout le monde essaie d'obtenir beaucoup d'informations tout le temps, ils ont décidé de mettre en place certaines règles ( cela ne reflète pas les règles réelles de l'API de YouTube ) :

  1. Vous ne pouvez demander qu'un maximum de 50 informations sur les chaînes/vidéos à chaque visite au bureau
  2. Vous ne pouvez venir au bureau que 10 fois par minute, 10 000 fois par jour
« Noooooon ! Je voulais vraiment avoir toutes les informations sur toutes les chaînes du monde !”

D'accord, alors nous devons être intelligents à ce sujet.

Faisons quelques calculs rapides pour déterminer le nombre maximum d'informations sur les canaux que nous pouvons demander par minute (et par jour).

Si on peut aller au bureau 10 fois/minute et à chaque fois, on peut demander 50 canaux : 10 x 50 = 50 canaux/min. En faisant un calcul similaire, nous réalisons que nous pouvons demander 10 000 x 50 = 50 000 canaux/jour.

Si vous développez cela un peu plus loin, vous vous rendrez compte que nous pouvons utiliser tout notre quota en 16 heures et 40 minutes - c'est-à-dire le temps qu'il faudra si nous demandons 50 canaux/min pour faire exploser notre quota de 50 000 canaux/jour.

Donc, la question en or ici est:

Comment pouvons-nous maintenir notre application à jour le plus efficacement possible avec les dernières informations sur les utilisateurs (même si nous avons plus de 50 000 utilisateurs) ?

Tout d'abord, établissons quelques règles de base de base pour nous-mêmes qui nous feront économiser quelques déplacements au bureau de YouTube et nous assurerons que nous suivons leurs règles. Divisons les responsabilités de cette tâche majeure en tâches plus petites qui sont exécutées par différents départements de notre entreprise :

  1. Appelons notre service chargé de contacter le bureau de YouTube le Scraper .
  2. Nous n'avons pas besoin de demander de nouvelles informations sur les chaînes si nous en avons déjà obtenu au cours des dernières 24h (nous sommes d'accord avec un délai de 24h pour mettre à jour les chaînes).
  3. Cela signifie que nous devons nous souvenir d'une manière ou d'une autre de la dernière information sur une chaîne et de l'heure à laquelle nous l'avons récupérée - appelons cela notre Cabinet .
  4. Nous voulons probablement avoir plus d'une personne capable d'aller au bureau — puisque YouTube a une limite de 50/min, nous pouvons optimiser notre processus en embauchant 50 personnes pour exécuter ce travail (appelons-les Runners )
  5. Nous devons avoir une sorte de contrôle sur le nombre de visites que nous effectuons à leur bureau dans une minute donnée et un jour donné (peut-être pouvons-nous l'écrire quelque part ? Appelons-le le journal des coureurs ) .
  6. Cela signifie également que chaque fois que nos coureurs veulent partir et saisir de nouvelles informations sur la chaîne, nous devons revérifier s'ils ne risquent pas de perdre leur voyage en raison de l'extrapolation de notre quota de minutes/jour. Ce centre de contrôle centralisé s'appellera le Département des Coureurs .
Le brouillon initial de notre flux de travail

Maintenant, qu'y a-t-il de si spécial dans ce flux à part le fait qu'il nous donne une première solution à (la plupart) de nos problèmes ?

Il fournit une séparation claire des préoccupations :

  • Le Scraper ne se soucie que d'obtenir des informations pour une chaîne YouTube (peu importe comment)
  • L' armoire ne se soucie que de stocker/récupérer les informations d'un canal
  • Le département des coureurs ne se soucie que de gérer les courses vers le bureau YouTube
  • Le journal des coureurs ne se soucie que du stockage/récupération des informations pour les courses
  • Le coureur assigné ne se soucie que de faire la course lui-même

C'est aussi le soi-disant concept de modularisation lié au couplage lâche .

Développons un peu le couplage lâche et comment cela rend notre système beaucoup plus évolutif. Pour le comprendre, nous devons comprendre pourquoi les interfaces (contrats) entre les modules sont importantes.

Prenons l'interaction entre le Scraper et le Cabinet , par exemple.

Ils doivent tous deux se mettre d'accord sur la manière dont ils vont se parler : le Cabinet va-t-il recevoir les demandes par téléphone ? Un SMS ? — Ils doivent également se mettre d'accord sur la manière dont le Cabinet va renvoyer les informations au Scraper : est-ce un dossier avec des fichiers ? Une pièce jointe par email ?

Tout ce qui compte, c'est qu'ils aient besoin d'avoir un accord, une interface, un contrat.

Pourquoi?

Une fois cette ligne établie, peu importe la complexité de la structure interne du Cabinet : pour tous les soucis de Scraper , il peut s'agir d'une opération d'une seule personne ou d'une armée de construction de cinq magasins.

Tant que le Cabinet peut respecter son contrat de manière fiable, tout va bien.

Cela nous permet, ainsi qu'à notre équipe de développement, de travailler de manière indépendante sur chacun de ces modules, en prenant les meilleures décisions pour ses performances internes.

On peut paralléliser le travail de chacun d'eux, car au final, tout ce qui compte c'est qu'ils sachent se parler.

Ce concept s'applique même dans notre vie de tous les jours : chaque fois que vous commandez quelque chose en ligne, vous souciez-vous généralement de savoir qui est le transporteur ? Savez-vous comment fonctionne en interne une calculatrice pour vous restituer les résultats ? Est-ce que tu en as quelque chose à faire?

Quelle beauté, hein ?

Que se passe-t-il si nous avons plus de demandes que nous ne pouvons en traiter ?

Mince, ça ne résout toujours pas l'un de nos principaux problèmes ! Nous allons constituer un arriéré que le Département Coureurs ne pourra peut-être pas résorber à temps !

Hein, oh. Cela n'a pas l'air amusant.

Il semble que nous ayons besoin d'une sorte de système pour nous assurer d'avoir un arriéré de ces opérations et de les gérer de la manière la plus efficace possible, en ne laissant aucune demande en suspens indéfiniment !

Élaborons quelques règles pour adapter le nombre de demandes au service des coureurs .

Certaines choses ( règles ) que nous pouvons proposer sont :

  1. Premier arrivé, premier servi : nous traitons les demandes comme une file d'attente. Cela garantit qu'à un moment donné, la demande d'informations pour un canal spécifique sera traitée. Nous ne pouvons tout simplement pas garantir quand.
  2. Donner la priorité aux canaux pour lesquels nous n'avons pas de données (nouveaux canaux dans notre application). Cela pourrait être une stratégie intelligente : un canal sur lequel nous n'avons aucune donnée signifie que l'utilisateur est probablement incapable d'utiliser l'application. c'est-à-dire qu'avoir des données obsolètes vaut mieux que de ne pas avoir de données du tout !
  3. Assurez-vous que nous n'avons pas de demandes en double dans notre backlog : s'il existe déjà une tâche en attente pour un canal spécifique, nous pouvons simplement ignorer les demandes supplémentaires qui lui sont adressées.

Passons en revue un exemple pour voir si tout cela a du sens.

Nous avons commencé notre journée avec une table rase - aucune demande en attente dans l'arriéré.

Du coup, nous avons un afflux de 7 000 requêtes : l'appli a désespérément besoin d'infos sur 7 000 chaînes ! Compte tenu de la logique que nous avons décrite ci-dessus, nous :

  1. Nettoyez toutes les demandes de canal en double qui pourraient se trouver dans ce lot
  2. Vérifiez les canaux pour lesquels nous n'avons pas d'informations passées ; déplacer ces canaux au début de la file d'attente
  3. Enregistrez la file d'attente dans notre journal des coureurs

Encore une fois, voici à nouveau la beauté de la modularisation : il s'agit d'un changement interne du fonctionnement du département des coureurs .

Le Scraper fonctionnera toujours de la même manière : il continuera à demander des informations sur les canaux (en tant qu'enfant gâté qu'il est !). C'est le problème du service des coureurs de stocker et de gérer cette file d'attente en interne.

N'oubliez pas : tous les autres modules concernés sont les contrats et les interfaces !

Phew!

D'accord, mon pote, c'était beaucoup - mais j'espère que cela avait autant de sens pour vous que pour moi en écrivant ceci.

Vous devriez maintenant avoir une très bonne compréhension de l'importance de la modularisation, du couplage lâche et des abstractions.

Vous savez maintenant aussi comment nous pouvons, avant même de commencer à taper du code, penser à concevoir un système qui peut évoluer indépendamment.

La prochaine fois que vous commencerez à concevoir un système, essayez de répondre aux questions fondamentales sur la façon dont vous pouvez concevoir de tels modules indépendants et faiblement couplés avant même de vous précipiter pour commencer à taper du code.

Sinon, vous risquez de commencer à développer le code hérité de demain que personne ne comprend et/ou ne veut gérer !