Quelle est la différence entre fonctionnel et technique?

0.4.5a (en cours de relecture) du 10/11/2017

Public ciblé par ce document:
  • participant à l'élaboration de dossier de choix de solution,
  • membre d'une équipe de fabrication logiciel (concepteur, testeur, développeur).

Introduction

Dans le cadre des activités de conception et de fabrication de logiciels, nous proposons une tentative de réponse à cette fameuse question.

Question énoncée simplement mais dont la compréhension de la réponse nécessite un peu de temps et d'attention dans l'objectif de mettre en lumière l'essence des activités de conception et de fabrication de logiciels.

Commençons par l'essentiel, le dictionnaire:
  • Fonctionnel: Qui a pour objet de déterminer le rôle, l'adaptation de tel élément d'un système à une fin.
  • Technique: Qui est relatif aux procédés utilisés pour la réalisation d'une activité particulière, au savoir-faire requis pour la maîtrise d'une tâche, d'une activité.

  • Il est important de savoir répondre à cette question et de pratiquer la conception fonctionnelle au sein d'une équipe de développement logiciel afin de:
  • éviter la fabrication de fonctionnalités innutiles ou mal conçues -nécessitant des réécritures coûteuses,
  • garantir que les choix techniques sont fait au regard d'un besoin en fonctionnalités. Et non nécessairement par défaut, ce qui peut conduire à des difficultés d'évolutions du système mis en oeuvre,
  • faciliter les migrations techniques, en diminuer les coûts; éviter le besoin d'ingénierie inverse,
  • améliorer votre capacité à communiquer sur les fonctionnalités de votre produit.

  • Le travail du concepteur ou de l'architecte logiciel se situe à la frontière entre l'organisation humaine et le système informatique. Pour l'analyse et la conception, l'UML est un langage visuel adapté permettant de synthétiser des informations par vue, en fonction de ce qu'on cherche à voir du système. Un système peut être une organisation humaine et/ou un outil informatique. UML propose le diagramme de classe[8], qui permet de définir des concepts et leurs imbrications. C'est une base et un préalable pour concevoir des structures de données physiques. Les diagrammes de cas d'utilisation[1][2][3][9], en UML, permettent de définir ce que peut faire un utilisateur avec le système. Nous nous concentrerons ici sur ces deux diagrammes qui sont très pratiques pour documenter un système ou plus simplement animer des ateliers de conception d'un système.

    L'agilité est une méthodologie prenant sa source dans les développements open source[4] et plus particulièrement dans leur apparente anarchie combinée à la revendication de savoir produire des outils de qualité rapidement[5]. Outre des principes de pilotage et de plannification, les méthodologies dérivées de cette culture, comme SCRUM, proposent de formaliser le résultat de la conception par le récit utilisateur[7]. Un récit utilisateur est une phrase simple dans le langage de tous les jours permettant de décrire avec suffisamment de précision le contenu d'une fonctionnalité à développer[6].

    Nous parlons ici uniquement de l'axe fonctionnel de l'architecture du système. L'axe processus [13] [14] et l'axe modèle métier [15], à l'échelle supérieure, peuvent être discutés longuement. Ils ne sont pas du périmètre de ce document. BPMN, un langage de modélisation de processus métiers, combiné à UML, sont des outils puissants de conception d'organisations et d'entreprises abondamment utilisée par des cadres d'architecture comme TOGAF[19].

    L'objectif de ce document est d'expliquer, par l'exemple, les principes de conception tout en montrant comment le langage UML et les préceptes agiles peuvent s'intégrer et se compléter dans le cadre d'une démarche de conception logicielle afin de diminuer le risque de réaliser des fonctionnalités inutiles ou mal conçues.

    L'exemple: une messagerie élémentaire

    Pour faciliter la transmission et la compréhension de concepts, il est important de les illustrer par un ou plusieurs exemples pratiques. Cela offre un espace concret dans lequel projeter les concepts afin de les appréhender et les comprendre.

    Nous prendrons l'exemple d'une messagerie instantanée particulière. L'idée est d'écrire sa conception, d'abord de manière purement conceptuelle, sans considération concrète d'implémentation technique puis décrite dans des environnements techniques différents afin de bien illustrer la différence entre une conception abstraite, dite fonctionnelle, sans apriori technique, et une conception concrète, dite technique, intervenant dans un environnement technique particulier.

    Nous proposons de décrire une messagerie publique élémentaire. La messagerie est partagée par tous les utilisateurs. Elle est élémentaire car il n'y a qu'un seul canal de discussion. Elle est publique car il n'y a aucune sécurité. Un utilisateur envoie un message qui peut ensuite être lu par tout le monde, y compris lui-même, à la suite de tous les messages déjà envoyés. A la saisie, un utilisateur envoie son alias et le contenu du message. Chaque message à un identifiant unique et il ne peut pas être supprimé.

    Nous commençons par décrire le modèle conceptuel de la messagerie. Ensuite, nous alimentons une description fonctionnelle de la messagerie pour finir avec une description de quelques possibilités d'implémentations techniques.

    Concept et objet de données physiques

    Durant l'activité de conception, il est nécessaire de commencer par le modèle conceptuel. Il permet de définir précisément les concepts manipulés par le système ou par les utilisateurs. Commencer par le modèle conceptuel assure que tous les membres de l'équipe partagent le même vocabulaire et, très tôt, une première idée abstraite du système. Cela permet d'exprimer les cas d'utilisations, et les liens avec la technique, sur la base d'un vocabulaire et de définitions partagées.

    Tous les concepts ne sont pas obligatoirement représentés par des données physiques dans le système final. Certains concepts restent abstrait pour l'utilisateur. Nous allons présenter les deux concepts de notre messagerie: la messagerie elle-même et les messages qu'elle contient. On peut les représenter sous forme de diagramme de classe:


    Textuellement: La messagerie agrège des messages.

    Le concept de messagerie
    La messagerie est, comme vu précédemment, une agrégation de messages non destructibles. Elle doit être visible de tout le monde. Elle n'a, par contre, pas de représentation physique. Elle est le système.

    Le concept de message
    Un message est un texte libre édité et envoyé, à une date et une heure précise, par un utilisateur identifié par son alias. Un message est unique au sein du système.

    Nom de la propriété Format Contrainte Description
    Identifiant Chaine de caractère Est unique dans le système L'identifiant du message
    Alias Chaine de caractère Néant L'alias de l'auteur du message
    Message Chaine de caractère Néant Le message
    Date et heure d'enregistrement Date et temps en ms Néant La date et l'heure d'enregistrement


    Objets physiques
    A partir du modèle conceptuel précédent, nous déclinons, pour l'exemple, deux conceptions techniques distinctes, l'une en CSV, l'autre en json. Il est ainsi possible d'observer qu'un concept peut prendre de multiples formes de données physiques.

    Données au format csv[16]
    id;alias;message;timestamp
    001;ocds;Hello la cie;2017/11/05 17:21
    001;bg;Hey!;2017/11/05 17:21
    001;sp;Yep!;2017/11/05 17:21
    002;ocds;Ava bien vous?;2017/11/05 17:22


    Données au format json[17]
    {
      "message": {
        "id": "001",
        "alias": "ocds",
        "message" : "Hello la cie",
        "timestamp" : "2017/11/05 17:21"
      },"message": {
         "id": "001",
         "alias": "bg",
         "message" : "Hey!",
         "timestamp" : "2017/11/05 17:21"
         }
      },"message": {
         "id": "001",
         "alias": "sp",
         "message" : "Yep!",
         "timestamp" : "2017/11/05 17:21"
      },"message": {
       "id": "001",
         "alias": "ocds",
         "message" : "Ava bien vous?",
         "timestamp" : "2017/11/05 17:22"
      }
    }


    Extensions
    • Proposer, sur base des exigences du chapitre précédent, un modèle alternatif. Justifier.
    • Proposer un nouveau mode d'implémentation. Justifier.
    • Imaginer une fonctionnalité d'une nouvelle exigence. Adapter le modèle en conséquence. Justifier.

    Fonctionnalités

    Les fonctionnalités doivent être exprimées, partagées et défiées par l'équipe de conception afin de s'assurer de bien capturer le besoin exprimé par les utilisateurs puis afin de s'assurer que le besoin est bien compris par l'équipe de développement.

    Nous présentons ici trois façons d'exprimer les fonctionnalités d'envoi de messages et de lecture des messages.

    Cas d'utilisations



    Cas d'utilisation numéro 1
    Nom: Lire les messages
    Description: L'utilisateur consulte les messages.
    Acteur: L'utilisateur.
    Scénario principal:
    • L'utilisateur consulte la liste de messages pour lesquels il peut observer l'identifiant du message, la date et l'heure d'enregistrement, l'alias de l'émetteur et le contenu du message
    Scénario alternatif: Néant.


    Cas d'utilisation numéro 2
    Nom: Envoyer un message
    Description: L'utilisateur envoie un message.
    Acteur: L'utilisateur.
    Scénario principal:
    • L'utilisateur saisi son alias
    • L'utilisateur saisi son message
    • L'utilisateur envoie son message
    Scénario alternatif: Néant.


    Récits utilisateur
    Récit numéro 1
    Nom: Lire les messages
    Description:En tant qu'utilisateur, je veux pouvoir consulter la liste des messages
    Conditions de validation:
    • Vérifier que les alias sont visibles
    • Vérifier que les contenus des messages sont visibles
    • Vérifier que les identifiants de messages sont visibles
    • Vérifier que la date et l'heure d'enregistrement des messages sont visibles


    Récit numéro 2
    Nom: Envoyer un message
    Description: En tant qu'utilisateur, je veux pouvoir envoyer un message dans la messagerie en saisissant mon alias et le contenu mon message.
    Conditions de validation:
    • Vérifier que le message peut être visualisé dans la liste de messages


    Fonctions
    Fonction numéro 1
    Nom: Lire les messages
    Description: Cette fonction permet de lire les messages contenus dans la messagerie.
    Entrées: néant
    Sorties: La liste des messages avec leur identifiant, leur alias et leur contenu.
    Pre-Condition: néant
    Post-Condition: néant


    Fonction numéro 2
    Nom: Envoyer un message
    Description: Cette fonction permet l'envoie d'un message par un utilisateur
    Entrées: l'alias et le message de l'utilisateur
    Sorties: néant
    Pre-Condition: néant
    Post-Condition: Le message est enregistré dans la messagerie avec un identifiant unique, une date et une heure d'enregistrement.

    Remarque: Au niveau supérieur, on constate que l'utilisation de la fonction comme élément descriptif porte un avantage décisif. Elle permet l'évaluation de complexité formelle (utilisation d'un cadre d'écriture d'algorithme en pseudo-langage, par exemple). Pour approfondir cette remarque, il existe Thêta, un cadre libre d'architecture d'entreprise[18] inspiré par TOGAF et ITIL.

    Discussion
    Décrire les fonctions laisse plus de latitude pour décrire les règles de fonctionnement interne. La lecture des fonctions est moins évidente que la lecture des cas d'utilisation car elles sont plus orientées système. En revanche, la description d'une fonction permet d'être exhaustif quant à la vue externe (nom de fonctions, paramètres d'entrée et de sortie, règles de gestion). Les fonctions sont plus proches du concept de fonction mathématique et sont adaptées aux langages objets (le concept de membre de classe) et à la conception d'API.

    Extensions
    • Proposer de nouvelles exigences et de nouveaux cas d'utilisation. Décrivez ces cas sous les trois formes.
    • Proposer une quatrième façon de décrire un cas d'usage. Justifier les avantages et inconvénients.
    • Identifier une limite technique amenant une modification de la fonctionnalité de lecture des messages. Décrire la nouvelle version de la fonctionnalité.

    Du fonctionnel à la technique [26]

    Autrement dit, de la fonctionnalité abstraite à l'interface utilisateur. Nous présentons six possibilités d'implémentations de la messagerie en décrivant les actions techniques nécessaires pour interragir avec le système. Cela illustre, sans pour autant être exhaustif, les nombreuses variations d'implémentations pouvant être déclinées d'un besoin fonctionnel unique. En résumé: l'idée conceptuelle ne fait pas l'implémentation. Au même titre que l'équipe de développement peut défier l'expression du besoin, amener des idées de fonctionnalités, les équipes de conception et de test peuvent orienter les choix techniques, critiquer de manière constructive l'usage de l'implémentation et proposer des idées d'amélioration de l'implémentation afin d'améliorer l'expérience utilisateur. A la fin du processus, à la livraison, c'est l'utilisateur qui tranche.

    Nous présentons ici quelques exemples de conception applicative. Nous ne présentons pas ici la conception matériel supportant ces fonctionnalités.

    Messagerie à la mode interface graphique [20]
    Envoyer un message
    L'utilisateur accède à shinoe.org/message.html
    Il y trouve deux champs texte, l'un pour son alias, l'autre pour le message ainsi qu'un bouton "envoyer".
    Il renseigne son alias et son message avant de cliquer sur "envoyer".
    Si le message a été envoyé avec succès, l'utilisateur se retrouve sur la même page, vidé du contenu; sinon un message d'erreur s'affiche: "erreur d'envoi du message".


    Lire les messages
    L'utilisateur accède à shinoe.org/messages.html
    Il y trouve les informations suivantes, en HTML brut sans mise en forme:
    001 ocds Hello la cie 2017/11/05 17:21
    001 bg Hey! 2017/11/05 17:21
    001 sp Yep! 2017/11/05 17:21
    002 ocds Ava bien vous? 2017/11/05 17:22


    Messagerie à la mode gitlab [21]
    Envoyer un message
    - L'utilisateur se log à framagit.org et accède à la page du projet shinoe
    - Dans le répertoire messages il crée un nouveau document auquel il donne le nom: @alias_@nummessage.md, (@nummessage étant unique pour l'alias).
    - Il écrit son message dans le corps du fichier.
    - Il l'enregistre et commit sa modification.


    Lire les messages
    - L'utilisateur se log à framagit.org et accède à la page du projet shinoe.
    - Dans le répertoire messages, il consulte les messages.

    Un scénario alternatif est d'utiliser directement l'interface en ligne de commande de git.

    Messagerie à la mode CLI sous linux [22]
    Envoyer un message
    L'utilisateur ocds sur la machine shinoe001 saisi en ligne de commande, dans le répertoire où se trouve les binaires sendMessage et readMessage:
    ocds@shinoe001:./sendMessage -alias="Olivier" -message="Hello la cie !"


    Lire les messages
    L'utilisateur ocds sur la machine shinoe001 saisi en ligne de commande, dans le répertoire où se trouve les binaires exécutables sendMessage et readMessage:
    ocds@shinoe001:./readMessages id alias message timestamp
    001 ocds Hello la cie 2017/11/05 17:21
    001 bg Hey! 2017/11/05 17:21
    001 sp Yep! 2017/11/05 17:21
    002 ocds Ava bien vous? 2017/11/05 17:22

    Messagerie à la mode API REST [23]
    Envoyer un message
    POST http://www.shinoe.org/message
    {
      "alias":"@ocds"
      "message":"Hello la cie!"
    }

    Lire les messages
    GET http://www.shinoe.org/messages
    {
      "message": {
        "id": "001",
        "alias": "ocds",
        "message" : "Hello la cie",
        "timestamp" : "2017/11/05 17:21"
      },"message": {
         "id": "001",
         "alias": "bg",
         "message" : "Hey!",
         "timestamp" : "2017/11/05 17:21"
         }
      },"message": {
         "id": "001",
         "alias": "sp",
         "message" : "Yep!",
         "timestamp" : "2017/11/05 17:21"
      },"message": {
       "id": "001",
         "alias": "ocds",
         "message" : "Ava bien vous?",
         "timestamp" : "2017/11/05 17:22"
      }
    }

    Messagerie à la mode librairie Python [24]
    Envoyer un message
    import messagerie
    messagerie.sendMessage("ocds","Hello la cie!")


    Lire les messages
    import messagerie
    print(messagerie.readMessages())


    A l'exécution, la commande print affichera les messsages.

    Messagerie à la mode librairie C++ [25]
    Envoyer un message
    #include IMessagerie.h
    IMessagerie->sendMessage("ocds","Hello la cie!");


    Lire les messages
    #include IMessagerie.h
    print(IMessagerie->getInstance()->readMessages());


    A l'exécution, la commande print affichera les messsages.

    Extensions
    • Etudier et proposer une stratégie de plugin et les cas d'usages associés. Justifier.
    • Imaginer l'intégration de ces fonctions dans un processus métier plus large. Décrire et justifier.
    • Proposer d'autres exemples d'implémentations. Discuter les avantages et les inconvénients.

    Expérience utilisateurs, testeurs, développeurs et concepteurs

    A partir des cas d'utilisations et des récits utilisateurs, on peut imaginer une infinité d'implémentations particulières, de cas d'usages pratiques particuliers, d'applications particulières en fonction des choix techniques.
    Cette activité consiste à rechercher le moyen le plus simple, le plus agréable et le plus efficace d'exécuter un cas d'utilisation. En changeant, par exemple, de techno UI, de dessins d'écrans ou simplement le mode d'accessibilité, vous pouvez changer complètement l'expérience d'utilisation d'un service. C'est la force du cas d'utilisation et du récit utilisateur: ils ne limitent pas l'exploration technique, il ne contraignent pas sur le mode d'implémentation. Ils permettent d'itérer sans fin jusqu'à identifier l'outil idéal concret pour les utilisateurs. Ils constituent, selon moi, la base d'un réacteur à innovation.

    Durant la fabrication d'un outil informatique, tous les intervenants vivent une expérience différente. Il est essentiel de porter une attention particulière à l'expérience que le système offre à tous les intervenants du projet et pas seulement à l'utilisateur final. Il est important de s'assurer que les outils techniques offrent une expérience de développement agréable aux développeurs, que les outils de tests offrent des interactions efficaces et pertinentes etc.

    Une ouverture, des ouvertures

    Notre ouverture est une réflexion sur le caractère itératif, par essence, de l'activité de conception. Nous pourrions faire un schéma résumé simplifié de l'itération, moteur des activités de conception:



    Globalement, les activités de conceptions interviennent dans un cycle de développement itératif plus global (cliquez sur l'image pour l'agrandir):



    Dans ce contexte, les concepteurs proposent, pratiquent et défient la modélisation, les utilisateurs la valident et la défient, les testeurs et les développeurs l'utilisent et la défient, la questionnent afin de l'améliorer.



    Si l'application ou l'outil est central à l'activité de votre organisation ou si c'est un produit populaire, il est envisageable que ce cycle itératif ne s'arrête jamais. Il y aura toujours de nouveaux usages, de nouvelles idées d'amélioration ou d'évolution, de nouvelles modes, de nouvelles envies, de nouveaux concepts, de nouvelles techniques qui viendront perturber et défier l'existant de par la potentielle valeur métier qu'ils portent. Il y a deux cas pour lesquels les outils n'évoluent pas: ils sont peu voir pas utilisés ou il n'y a pas les moyens pour les faire évoluer.

    Sauf pour certains cas élémentaires, il est impossible de faire une bonne conception du premier coup, sans que cette dernière ait été confrontée à une réflexion approfondie et un questionnement constant de la part des intervenants du projet (utilisateurs, testeurs, développeurs et concepteurs). De nombreuses versions sont à attendre afin de concevoir un produit à l'état de l'art. Il est envisageable par exemple, de revoir la conception technique et l'implémentation générale d'un outil informatique simplement par la découverte d'une nouvelle fonctionnalité, par l'émergence d'un nouveau concept ou par la meilleure compréhension d'un concept existant.

    En voici un exemple personnel, sur le développement de Caméléon[10][11], nous avons compris durant la deuxième version, après 3 ans de développement, le caractère profond de la synchronisation de processus que nous avons réussi à formaliser en langage mathématique[12]. C'est à partir de ce moment-là que nous avons entrepris une réécriture depuis zéro du langage afin d'y intégrer proprement les nouveaux concepts et les fonctionnalités associées. Notre décision a été prise sur la base de la comparaison des évaluations du coût d'adaptation et du coût de réécriture. Parfois, il est plus accessible de tout casser et de tout refaire.

    Autre exemple, qui montre qu'un changement conceptuel majeur n'implique pas forcément un changement technique important: toujours pour Caméléon, de l'usage de la composition multi-échelle. Cette fonctionnalité, apparue en fin de version 3, a demandé une adaptation partielle du système et l'adaptation, légère, de notre machine virtuelle alors même que l'évolution conceptuelle était majeure. Notre décision a été prise sur la même base que la précédente: coût d'adaptation versus coût de réécriture complète.

    Remarque: Un produit revu trop souvent depuis zéro indique un manque de maturité conceptuelle et fonctionnelle.

    Il est tout à fait possible d'avoir un backlog de produit (ref. scrum à ajouter) matérialisant des récits, des cas d'utilisations et des descriptions de fonctions, en fonction du besoin. La fonction est plus adaptée pour les API quand les cas d'utilisations et les récits sont plus adaptés à la description d'intéractions utilisateurs et, souvent, d'écrans.

    Il est tout à fait possible que les cas d'utilisation et les récits fassent références à un outil technique ou une technologie particulière si cette dernière a déjà été identifiée comme faisant partie de l'architecture technique. L'exemple de l'implémentation de la messagerie via gitlab en est une bonne illustration. Cela représente un choix par défaut contextuel allant au plus pragmatique et au moins cher, au détriment, peut-être, de l'expérience utilisateur.

    Il est indispensable de recevoir des retours d'utilisateurs et d'échanger avec eux sur leurs usages du système (vous pourriez être surpris de leur créativité à le détourner pour trouver des usages cachés). Il faut donc utiliser au maximum le sondage et les ateliers de relecture du besoin et de partage des exigences afin de s'assurer que l'expression du besoin est bien une image des attentes des utilisateurs puis trouver des axes d'amélioration et d'évolution. Sans échanges ni utilisateurs, un outil n'existe pas.

    Références

    • [1] http://www.uml-diagrams.org/use-case-diagrams.html
    • [2] http://www.agilemodeling.com/artifacts/useCaseDiagram.htm
    • [3] https://en.wikipedia.org/wiki/Use_case_diagram
    • [4] https://fr.wikipedia.org/wiki/La_Cath%C3%A9drale_et_le_Bazar
    • [5] http://agilemanifesto.org/
    • [6] https://fr.wikipedia.org/wiki/R%C3%A9cit_utilisateur
    • [7] http://mbf-iut.i3s.unice.fr/lib/exe/fetch.php?media=2014_2015:s3:methodo:userstories.pdf
    • [8] https://en.wikipedia.org/wiki/Class_diagram
    • [9] https://openclassrooms.com/courses/debutez-l-analyse-logicielle-avec-uml/la-description-textuelle-d-un-cas-d-utilisation
    • [10] https://en.wikipedia.org/wiki/Cameleon_%28programming_language%29
    • [11] http://www.shinoe.org/cameleon
    • [12] https://arxiv.org/abs/1110.4802
    • [13] BPMN: https://fr.wikipedia.org/wiki/Business_process_model_and_notation
    • [14] Workflow patterns: http://www.workflowpatterns.com/
    • [15] BMG: https://www.amazon.fr/Business-Model-Generation-Visionaries-Challengers/dp/0470876417
    • [16] https://fr.wikipedia.org/wiki/Comma-separated_values
    • [17] https://fr.wikipedia.org/wiki/JavaScript_Object_Notation
    • [18] https://framagit.org/ocds/Theta
    • [19] TOGAF: https://fr.wikipedia.org/wiki/The_Open_Group_Architecture_Framework
    • [20] https://fr.wikipedia.org/wiki/Interface_graphique
    • [21] https://fr.wikipedia.org/wiki/GitLab_CE
    • [22] https://fr.wikipedia.org/wiki/Interface_en_ligne_de_commande
    • [23] http://rest.elkstein.org/
    • [24] https://fr.wikipedia.org/wiki/Python_%28langage%29
    • [25] https://fr.wikipedia.org/wiki/C%2B%2B
    • [26] https://fr.wikipedia.org/wiki/Interface_utilisateur