Systèmes FileMaker maintenables · Article 8 sur 18

Les méthodes : l’unité contractuelle

Quand chaque surface structurelle a été rendue inerte, il ne reste qu’un seul endroit où le comportement peut exister. Cet article l’identifie — et définit ce qu’il exige.

L’article 7 a fermé la dernière surface ouverte. Le graphe ne décide pas. Les noms n’encodent pas de règles. Le schéma ne produit pas de résultats. Aucun artefact structurel du système ne porte de comportement.

Ce n’est pas un résultat négatif. C’est une preuve par élimination.

Si le comportement ne peut pas vivre dans le graphe, ne peut pas vivre dans le schéma, ne peut pas vivre dans les noms, ne peut pas vivre dans la structure des fichiers, et ne peut pas vivre dans les mécanismes d’accès aux données — alors il vit ailleurs. Cet ailleurs n’est pas une préférence de conception. C’est là où convergeait la série de contraintes.

Cet article identifie cet endroit et définit ce que tout ce qui l’occupe doit satisfaire.


Nouveaux concepts introduits

  • Classe de méthode
  • Identité de méthode
  • Frontière de pureté de méthode

Ce qui a été éliminé et ce qui reste

Partons de ce qui a déjà été retiré.

La structure des fichiers ne peut pas porter de comportement. L’article 5 a établi que l’application des contraintes exige une séparation physique. Les fichiers sont des frontières, pas des conteneurs de logique. Un fichier qui possède du comportement viole la séparation des couches. Le fichier est une surface d’application, pas une surface comportementale.

Le graphe relationnel ne peut pas porter de comportement. L’article 7 a établi que les résultats comportementaux ne doivent pas dépendre de la topologie relationnelle. Si le retrait ou la neutralisation d’une relation change le comportement du système, la relation portait du comportement. Une relation valide fournit du contexte ou de l’accessibilité, pas la propriété du comportement. Un comportement encodé dans la topologie du graphe est un comportement qui ne peut pas être inspecté, audité, ni appliqué.

Le schéma ne peut pas porter de comportement. Les règles de saisie automatique, les validations déclenchées et les valeurs calculées qui pilotent des résultats sont du comportement déguisé en structure de données. Ils sont invisibles pour le modèle d’exécution et ne peuvent pas être gouvernés comme du comportement.

Les noms ne peuvent pas porter de comportement. Les conventions de nommage existent pour rendre la structure lisible et auditable. Un nom qui encode une règle est une convention appliquée par la lecture — et les conventions appliquées par la lecture échouent quand la lecture est incomplète.

Les contraintes d’accès aux données explicites ne peuvent pas porter de comportement. Le modèle d’accès aux données établi dans l’article 7 gouverne comment les données sont atteintes, pas ce qui en est fait. La politique d’accès est une contrainte sur le comportement. Ce n’est pas du comportement.

Chaque surface structurelle qui aurait pu posséder du comportement a maintenant été éliminée comme autorité comportementale.

Après tout ça, il reste quelque chose. La couche logique possède les méthodes. L’article 2 a introduit cette phrase. Les articles 3 à 7 étaient, entre autres choses, une longue démonstration de ce qu’elle signifie. Chaque surface structurelle qui aurait pu absorber du comportement a maintenant été fermée. La couche logique est ce qui reste. Les méthodes sont ce que la couche logique contient.

La question qui suit n’est pas de savoir si les méthodes sont le bon choix de conception. La question est : que doit être quelque chose pour occuper cette place ?


Le problème avec les scripts

FileMaker donne aux développeurs des scripts. Les scripts sont le mécanisme d’exécution de FileMaker. C’est là que les étapes s’exécutent, que la logique s’accumule, que le comportement vit en pratique.

Le problème n’est pas que les scripts sont peu fiables. Le problème est qu’un script est un artefact FileMaker, pas une unité architecturale.

Un script peut être modifié : ses étapes peuvent être changées à tout moment, sans altérer quoi que ce soit qui y fait référence par son nom. Un script peut être renommé : son nom n’a pas de statut contractuel. Un script peut être déplacé : il peut être déplacé entre fichiers, entre dossiers, entre contextes. Un script n’a pas d’entrée contractuellement déclarée — il reçoit des paramètres via un mécanisme qui n’impose aucune structure. Un script n’a pas de sortie contractuellement déclarée — il retourne ce que l’étape Quitter script fournit, dans le format choisi au moment où il a été écrit.

Rien de tout ça n’est un échec de FileMaker. C’est une description de ce qu’est un script : un mécanisme d’implémentation. Les scripts existent pour exécuter des étapes. Ils n’existent pas pour posséder du comportement.

Le problème survient quand un script est traité comme s’il possédait du comportement — quand le modèle comportemental du système est construit directement sur les noms de scripts, les dossiers de scripts et les appels de scripts. C’est le modèle par défaut. Et c’est ce dont les contraintes établies dans l’article 2 exigent de s’éloigner.

La raison est précise : un script ne fournit pas l’identité comportementale stable que cette architecture exige. Son nom peut changer. Son emplacement peut changer. Ses étapes peuvent changer. Ce qu’il fait peut changer. Rien dans un script n’est contractuellement fixé par FileMaker. Une architecture construite sur des scripts est une architecture construite sur des éléments mutables, sans identité déclarée, sans contrat explicite. Elle ne peut pas être raisonnée comme du comportement, parce que les scripts ne sont pas l’unité de comportement.

Ça ne rend pas les scripts inutiles. FileMaker exécute des scripts, pas des méthodes. Une méthode exige une implémentation, et dans FileMaker cette implémentation est typiquement un ou plusieurs scripts. La méthode exprime l’intention comportementale. Le script réalise cette intention dans les termes d’exécution de FileMaker. Le comportement appartient à la méthode. Le script est le mécanisme par lequel il s’exécute. Les deux occupent des positions différentes dans le modèle — et confondre ces positions produit précisément les conditions décrites dans les articles précédents.

L’architecture exige donc une unité que les scripts ne peuvent pas être. Quelque chose d’autre l’est.


Ce qu’est une méthode

Une méthode est une unité de comportement liée par contrat, avec une entrée et une sortie déclarées, indépendante du contexte d’exécution.

Cette définition a été introduite dans l’article 2. Ce que les articles précédents n’ont pas fait — parce que ce n’était pas le bon endroit — c’est la rendre opérationnelle. C’est ici que ça se passe.

Le terme méthode désigne un rôle architectural dans ce modèle. Ce n’est pas un artefact FileMaker. Ce n’est pas un construit de FileMaker. Ça ne fait référence à rien que FileMaker fournit ou nomme. Ça fait référence à une position dans le modèle comportemental : la position occupée par une unité de comportement qui satisfait les exigences contractuelles définies ici.

La définition contient trois affirmations qui requièrent chacune une attention particulière.

Liée par contrat. Une méthode a un contrat. Le contrat déclare quelle entrée la méthode accepte, quelle sortie elle produit, et quelles erreurs elle peut retourner. Le contrat est stable. L’implémentation derrière lui n’est pas tenue de l’être. Une méthode dont le contrat change a changé d’une façon qui est visible, auditable et gérée. Une méthode dont l’implémentation change, mais dont le contrat ne change pas, a été refactorisée. Les deux événements sont catégoriquement différents. Un script les traite de façon identique.

Entrée et sortie déclarées. L’entrée n’est pas héritée du contexte. Elle n’est pas lue depuis une variable globale. Elle n’est pas inférée depuis l’enregistrement actif ou l’ensemble trouvé. Elle est déclarée — passée explicitement, avec une structure définie, avant que l’exécution commence. La sortie n’est pas un effet de bord. Elle est retournée — avec une structure définie, via un canal de retour déclaré. Une méthode qui requiert une entrée non déclarée pour fonctionner n’est pas une méthode. C’est une implémentation qui ne satisfait pas aux exigences d’une méthode.

Indépendante du contexte d’exécution. C’est la clause la plus conséquente. Le modèle exige que le résultat d’une méthode dépende uniquement de l’entrée déclarée et des données explicitement accédées, pas du contexte d’exécution. Le modèle actif au moment de l’exécution ne doit pas altérer sa sortie. L’ensemble trouvé présent en mémoire ne doit pas altérer sa sortie. La fenêtre ouverte à l’écran ne doit pas altérer sa sortie. La variable globale définie par une opération précédente ne doit pas altérer sa sortie. Si l’un de ces éléments altère la sortie, la méthode a une dépendance qu’elle n’a pas déclarée. C’est une violation de contrat.


Identité de méthode

Un script est identifié par son nom et son identifiant interne. Le nom est une chaîne de caractères. L’identifiant est un entier FileMaker. Ni l’un ni l’autre ne constitue une identité comportementale.

Une méthode a une identité logique : module.méthode.

Le module est une frontière de propriété logique — un espace de nom qui regroupe des méthodes liées sous une responsabilité cohérente. Le module n’est pas un fichier. Un fichier peut publier des méthodes pour plusieurs modules. Un module n’est pas un dossier. Un dossier regroupe des scripts physiquement ; un module regroupe des méthodes logiquement.

Le nom de la méthode, au sein d’un module, identifie une unité de comportement spécifique. La combinaison — module.méthode — est l’identité qui persiste à travers tous les changements qui n’altèrent pas le contrat.

Cela signifie : un script qui implémente invoicing.calculateTotal peut être renommé, déplacé ou remplacé. L’identité de la méthode ne change pas. Le contrat ne change pas. Chaque partie du système qui appelle invoicing.calculateTotal continue d’appeler la même chose. L’implémentation a changé. Le comportement — du point de vue du système — n’a pas changé.

Ce n’est pas une convention. C’est une exigence architecturale. Sans identité stable, le comportement ne peut pas être référencé de façon fiable. Sans référence fiable, le comportement ne peut pas être gouverné. Sans gouvernance, l’architecture s’effondre dans les mêmes conditions que celles que l’article 3 a décrites : un système où les conséquences du changement ne peuvent pas être prédites, parce que les unités de comportement n’ont pas d’identité fixe.

Un script peut avoir une identité FileMaker. Il n’a pas d’identité comportementale. Une méthode en a une. Ce n’est pas un détail. C’est la frontière entre implémentation et architecture.

Trois niveaux d’identité opèrent dans ce modèle, et ils ne doivent pas être confondus. L’identifiant interne du script est l’identité d’implémentation — c’est l’identifiant interne par lequel FileMaker maintient l’identité du script. Le nom module.méthode est l’identité logique — c’est ce que le modèle comportemental utilise pour référencer une unité de comportement tout au long de sa vie. Le contrat est la frontière de continuité comportementale — c’est ce qui détermine si la méthode a changé d’une façon qui importe architecturalement. Un script peut être remplacé et l’identité logique demeure. Un contrat peut changer et l’identité logique demeure — mais la méthode a changé d’une façon que l’architecture doit suivre. Ce sont trois choses différentes. L’architecture raisonne sur les trois, mais seule l’identité logique (module.méthode) constitue l’identité comportementale.

Diagramme comparant un script en tant qu'artefact FileMaker mutable avec une méthode en tant qu'unité de comportement liée par contrat, avec une identité déclarée, une entrée et une sortie
Un script est identifié opérationnellement par les mécanismes de FileMaker. Une méthode est identifiée comportementalement par son identité logique et son contrat. Les deux ne sont pas des unités architecturales interchangeables.

Classes de méthode

Toutes les méthodes ne sont pas de la même nature. Les unités comportementales ne peuvent pas être gouvernées si tout comportement est traité comme étant de même nature. L’architecture doit pouvoir raisonner sur les effets qu’une méthode est autorisée à produire avant que l’exécution commence. Les classes de méthode fournissent cette distinction. Trois classes existent, et une méthode doit appartenir à exactement l’une d’entre elles.

Une méthode de lecture lit. Elle accède aux données, calcule un résultat et le retourne. Elle ne valide ni n’enregistre aucune modification. Elle ne crée ni ne détruit rien. Elle est sans effets de bord. Le modèle exige que le même appel avec la même entrée produise la même sortie. Une méthode de lecture qui produit des effets de bord n’est pas une méthode de lecture. C’est une écriture non déclarée.

Une méthode d’écriture effectue une mutation. Elle possède la mutation qu’elle effectue. La validation se produit à l’intérieur de la méthode, avant la persistance. Le modèle exige que l’écriture soit traitée comme transactionnelle — la méthode retourne un résultat structuré qui déclare si l’opération a réussi ou échoué, et les mutations partielles ne sont pas autorisées, pour ne pas laisser le système dans un état indéfini. La transactionnalité est une exigence architecturale du modèle de méthodes. Le mécanisme d’implémentation appartient au modèle d’exécution de FileMaker. Une méthode d’écriture qui délègue la validation à l’appelant n’a pas possédé sa mutation.

Une méthode d’interface encapsule un script d’interface. Elle existe pour que le comportement d’interface implémenté dans un fichier d’interface spécifique puisse être exposé via le même modèle de routage et de contrat utilisé pour toutes les autres méthodes. Cela permet à d’autres fichiers d’interface d’invoquer ce comportement sans créer de dépendances directes sur le script sous-jacent. La méthode d’interface ne contient pas de règles métier propres. Elle extrait les informations du contrat reçu, délègue à un script d’interface et retourne un résultat standardisé. L’existence de l’encapsulation ne fait pas du script d’interface une méthode. La méthode d’interface est l’unité architecturale. Le script d’interface est l’implémentation. Une méthode d’interface publie une capacité d’interface ; le script d’interface l’exécute.

Sans méthodes d’interface, les interactions d’interface entre fichiers exigeraient des références directes aux scripts, créant un second modèle d’invocation parallèle au routage par méthodes. Les méthodes d’interface préservent un modèle d’exécution unique à travers l’architecture.

La classe de méthode n’est pas une étiquette appliquée après coup. Elle est déterminée par ce que la méthode fait. Une méthode qui prétend être une lecture mais enregistre des données n’est pas une lecture avec une exception. C’est une écriture qui ne s’est pas déclarée. La distinction existe parce que la capacité du système à raisonner sur le comportement dépend de savoir à l’avance quel type d’effet une méthode aura.

Les classes de méthode sont une classification architecturale. Elles décrivent ce que fait une méthode dans le modèle comportemental. Elles ne disent rien sur la façon dont une méthode est implémentée dans FileMaker. Une méthode peut être implémentée par un seul script ou par plusieurs scripts coopérant entre eux. Tous les scripts n’existent pas pour implémenter directement une méthode — les scripts d’implémentation peuvent jouer des rôles différents au sein du modèle d’exécution. Ces rôles appartiennent au modèle d’implémentation, pas à la définition architecturale d’une méthode. Ils seront abordés plus loin dans la série.


La frontière de pureté

La chose la plus conséquente que cet article établit est ce qu’une méthode ne peut pas toucher.

Les articles précédents ont éliminé l’état implicite des surfaces structurelles : le graphe, le schéma, le système de nommage, le modèle d’accès aux données. La méthode est l’endroit où ces éliminations deviennent opérationnelles. Chaque forme d’état implicite qui a été retirée de la structure doit également être absente de l’environnement opérationnel de la méthode.

Une méthode ne peut opérer que sur trois choses :

  • son entrée déclarée
  • les données auxquelles elle accède explicitement via des requêtes pilotées par des paramètres
  • sa propre logique interne

Une méthode ne peut pas dépendre :

  • du modèle actif
  • de l’enregistrement actif
  • de l’état d’ensemble trouvé ambiant hérité du contexte
  • de l’état de fenêtre
  • des variables globales
  • de l’état de l’interface
  • du contexte de navigation

Ces dépendances sont précisément ce que l’article 3 a nommé comme des défaillances. Contexte implicite. État ambiant. Origine d’exécution comme paramètre caché. Les contraintes établies dans l’article 2 ont été conçues pour les éliminer. La méthode est l’endroit où cette élimination est appliquée au niveau de l’unité de comportement.

La raison pour laquelle cette liste importe : ce ne sont pas de mauvaises pratiques. Ce sont des dépendances qui ne peuvent pas être déclarées. Une méthode qui dépend du modèle actif ne peut pas recevoir cette dépendance en entrée — elle doit la lire depuis le contexte ambiant. Une méthode qui dépend d’une variable globale ne peut pas déclarer cette dépendance dans son contrat — elle doit lire la variable au moment de l’exécution. Une méthode qui dépend d’un état d’ensemble trouvé ambiant ne peut pas garantir un comportement cohérent — l’ensemble trouvé hérité du contexte change avec la navigation, avec l’action de l’utilisateur, avec l’exécution précédente.

Chaque élément de la liste des interdits est une forme d’entrée cachée. Les entrées cachées sont le mécanisme par lequel la dépendance au contexte réintègre un système construit pour la prévenir. La frontière de pureté est la surface d’application qui les maintient à l’extérieur.

Une méthode qui viole la frontière de pureté n’est pas une méthode au sens architectural. Elle demeure uniquement une implémentation de script dépendante du contexte. L’architecture ne la voit pas comme du comportement. C’est un résidu.

Diagramme montrant ce qu'une méthode peut accéder — entrée déclarée, données pilotées par paramètres, logique interne — séparé par une frontière de ce dont elle ne peut pas dépendre : modèle actif, enregistrement actif, ensemble trouvé, état de fenêtre, variables globales, état de l'interface et contexte de navigation
La frontière de pureté sépare les entrées explicites du contexte ambiant. Une méthode n'opère que sur ce qui a été déclaré. Tout ce qui se trouve de l'autre côté de la frontière est une entrée cachée.

Invisibilité architecturale

La frontière de pureté produit une classification, pas un spectre.

Une unité d’exécution satisfait les exigences de méthode ou elle ne les satisfait pas. Il n’y a pas de conformité partielle. Un script qui dépend d’une variable globale pour un cas limite est dépendant du contexte. Un script qui lit l’enregistrement actif par souci d’efficacité est dépendant du contexte. Un script qui vérifie le modèle actif pour brancher sa logique est dépendant du contexte.

L’architecture ne reconnaît pas les unités d’exécution dépendantes du contexte comme du comportement. Elles existent dans l’implémentation. Elles n’existent pas dans le modèle.

Ce n’est pas un jugement. C’est une conséquence structurelle de ce qu’exige un modèle comportemental. Un modèle qui raisonne sur le comportement doit pouvoir énumérer les unités de comportement, les identifier par une identité stable, et prédire leurs sorties depuis leurs entrées. Un script dépendant du contexte ne peut pas être placé dans ce modèle. Il n’a pas d’identité stable. Sa sortie ne peut pas être prédite depuis son entrée seule. Le modèle ne le refuse pas. Le modèle ne peut pas le contenir.

Ce que ça signifie en pratique : une solution FileMaker contient des scripts. Certains de ces scripts satisfont les exigences de méthode. Le comportement qu’ils implémentent se qualifie comme une méthode dans le modèle architectural. Le reste est du détail d’implémentation — scripts utilitaires, utilitaires d’interface, séquences de navigation, mécanismes internes de FileMaker. Ils ne font pas partie du modèle comportemental. Quand l’architecture est décrite, ils ne sont pas inclus. Quand le comportement est audité, ils ne sont pas examinés comme du comportement. Ils sont invisibles pour le modèle, non pas parce qu’ils sont cachés, mais parce que le modèle n’a pas de catégorie pour eux.

C’est aussi un diagnostic utile. Si un système contient beaucoup de scripts et peu de méthodes, c’est un système où le comportement n’est pas géré. L’architecture n’a pas identifié ses propres unités. Raisonner sur le système exige de lire chaque script, de comprendre chaque dépendance, de reconstruire chaque chemin d’exécution. C’est la condition dont les articles 1 à 7 s’éloignaient. La méthode est l’unité qui rend l’alternative possible.


Ce que ça rend possible — et ce que ça ne ferme pas encore

Définir la méthode ferme une question précisément : qu’est-ce qui est autorisé à exister dans cette architecture comme comportement ?

La réponse est : uniquement des unités liées par contrat, indépendantes du contexte, avec une entrée et une sortie déclarées et une identité logique stable.

Cette réponse n’est pas encore un modèle d’exécution complet. Une méthode définie isolément ne peut pas être appelée sans mécanisme d’invocation. Un contrat ne peut pas être appliqué sans une frontière qui le valide. Une identité logique ne peut pas être résolue sans un registre qui la fait correspondre à une implémentation. Ces choses appartiennent aux articles suivants.

Ce que cet article établit, c’est l’unité. L’unité est le prérequis à tout ce qui suit. Le routage exige quelque chose à router. Les contrats exigent une unité qu’ils gouvernent. Les frontières d’exécution exigent une unité capable d’y entrer et d’en sortir. La méthode est cette unité.

L’architecture dispose maintenant d’un modèle complet de propriété comportementale. Les fichiers appliquent la séparation des couches. Les règles d’interaction gouvernent ce qui peut appeler quoi. Le graphe ne porte que le contexte de présentation. L’accès aux données est explicite et piloté par paramètres. Les noms identifient sans encoder de règles. Et le comportement n’existe que sous forme de méthodes liées par contrat avec une identité déclarée et des contraintes de pureté définies.

Le système peut maintenant décrire son propre comportement — non pas en lisant des scripts, mais en lisant le modèle de méthodes.

Un système ne peut pas raisonner sur le comportement si le comportement est attaché à des artefacts d’implémentation. Les scripts changent. Les noms de scripts changent. Les identifiants de scripts sont internes. Rien dans un script ne constitue une identité comportementale stable.

Le comportement exige une identité qui survive à l’implémentation. Cette identité est la méthode.

Ressources complémentaires

Cet article reflète ma propre expérience et ma perspective. De nombreuses idées ici ont été façonnées par des contributions venues de forums, de communautés, de blogues et de livres blancs. Des outils d'IA ont été utilisés comme assistant à la rédaction pour structurer et affiner le contenu.

Discussion

La discussion est ouverte pour cet article. Les questions, objections, corrections et contre-exemples sont bienvenus.

Envoyer un commentaire privé