Les 3 lois de la Robotique appliquées à la Programmation Orientée Objet

En tant que développeur junior, j’avais parfois du mal à anticiper les conséquences de choix architecturaux, et je privilégiais parfois la simplicité et la lisibilité à ce que j’interprétais comme de la pureté théorique.

La vie, bonne pédagogue, m’a donné l’occasion de constater la sagesse des principes SOLID.

Les noms des principes forment un acronyme intéressant, mais sont un peu cryptiques pris individuellement. Est-ce qu’ils seraient plus facile à comprendre et mémoriser si on les présente comme les lois de la Robotique d’Asimov ?

Tags : OOP Rails Code architecture

Publié le 30 mars 2026

Si vous n’êtes pas familier des Lois de la Robotique d’Asimov, un rapide rappel :

  1. Un robot ne peut porter atteinte à un être humain ni, restant passif, laisser cet être humain exposé au danger ;
  2. Un robot doit obéir aux ordres donnés par les êtres humains, sauf si de tels ordres entrent en contradiction avec la Première Loi ;
  3. Un robot doit protéger son existence dans la mesure où cette protection n’entre pas en contradiction avec la Première ou la Deuxième Loi.

Une loi supplémentaire, jugée prioritaire, fut ajoutée plus tard — c’est pourquoi on l’appelle la loi « zéro » :

Un robot ne peut porter atteinte à l’humanité ni, restant passif, laisser l’humanité exposée au danger.

Les Trois Lois de la Robotique sur Wikipédia

Ces lois sont des directives générales, qui se traduisent en règles de conduite dans la société ; tout comme les principes SOLID garantissent que les objets interagissent entre eux sans enfreindre les règles métier.

Traduction en Orienté Objet

L’un des principaux enjeux de la Programmation Orientée Objet est de définir (et de respecter) les frontières entre les objets. Si l’on considère les modèles comme des robots interagissant avec d’autres entités, on peut traduire les lois d’Asimov ainsi :

  1. Un modèle ne doit pas modifier directement les données d’un autre modèle ni, via des callbacks, permettre que les données d’un autre modèle soient modifiées.
    En résumé : Ne modifiez pas les données internes d’un autre modèle.
  2. Un modèle doit honorer le contrat exposé par ses méthodes publiques, et signaler lorsqu’il doit refuser d’agir pour prévenir une corruption des données.
    En résumé : Respectez les messages que vous recevez.
  3. Un modèle doit protéger ses données — via des validations, des accesseurs internes, et des contraintes en base de données.
    En résumé : Protégez vos données de toute corruption.
  4. Un modèle ne doit pas corrompre les données métier ni, par une adhérence rigide aux autres lois, laisser des règles métier être violées.
    En résumé : Utilisez des objets dédiés pour coordonner les lectures ou modifications sur plusieurs modèles.

Appliquer ces lois avec Rails

Rails est connu pour fournir des outils à double tranchant, et ActiveRecord en particulier contient tout un arsenal pour se tirer dans le pied : callbacks, raccourcis contournant les validations, etc.

  1. La première loi interdit totalement les callbacks qui modifient d’autres modèles, ainsi que les appels à update_columns sur un autre modèle. Notez que les options d’association :touch, :counter_cache et :dependent sont assez limites à cet égard. Elles sont tolérées, parce qu’elles apportent plus de commodité que de risques. Les callbacks en revanche nécessitent une discipline stricte : un after_save qui appelle other.update(…) est un code smell de premier ordre, et devrait être remplacé par une meilleure architecture. C’est difficile à détecter automatiquement, mais RuboCop::CallbackChecker tente de repérer les callbacks mal utilisés.

  2. Pour appliquer la loi 2, il est préférable de rendre tous les accesseurs et méthodes privés, sauf s’ils se justifient comme méthodes publiques. Cela aide également à prévenir les chaînes de messages. Enfin, les méthodes doivent informer leur appelant lorsqu’elles ne peuvent pas continuer.

  3. La troisième loi impose de valider les données, y compris par des contraintes en base de données (index unique, clés étrangères…). La règle Rubocop Rails/SkipsModelValidations applique cette loi, en interdisant notamment save(validate: false).

  4. Enfin, comme les règles métier nécessitent souvent des modifications simultanées dans plusieurs modèles, il faut pour obéir à la loi zéro créer des méta-objets dont le rôle est de coordonner les lectures et les écritures multi-modèles, pour prévenir les incohérences. Les Service, Form et Query Object sont des façons typiques de respecter cette loi.

La science-fiction peut aider à s’évader mais elle permet également d’imaginer les conséquences de certains choix. Rappelez-vous donc que dans les histoires d’Asimov, chaque infraction aux lois de la Robotique finit par mal se terminer. S’il fallait donc retenir une chose, c’est que chaque fois qu’on est tenté d’enfreindre l’une de ces lois, c’est signe qu’une correction architecturale s’impose.

Page précédente Page précédente Page suivante Page suivante