• Aucun résultat trouvé

[PDF] Programmation web université guide de formation | Cours Informatique

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Programmation web université guide de formation | Cours Informatique"

Copied!
16
0
0

Texte intégral

(1)

A

rticle

Développer (… et maintenir) une

application Web à moindre coût

(2)

1.

Introduction

Dans le développement d’applications, le premier réflexe est d’estimer le coût de réalisation. Ce coût est, dans l’immense majorité des cas, une contrainte déterminante dans le choix de la solution (architecture, choix de logiciel, affinage du périmètre, …).

L’analyse le cycle de vie d’une application montre que l’intégration et la maintenance sont les deux principaux postes de coût. Ils représentent à eux deux 75% du total.

Mon approche consiste donc à minimiser ces postes, sans pour autant impacter significativement le coût initial. En effet pour un projet au cout réel de 2000j, il y aura eu en moyenne 100j de développements et 1360j d’intégration et maintenance. Donc toute méthode permettant de diminuer les coûts ne serait-ce que de 10% (-136j), quitte à doubler les coûts de développement (100j) est économiquement rentable sur le long terme.

Une architecture modulaire (https://en.wikipedia.org/wiki/Component-based_software_engineering) consiste à définir de manière précise chaque composant d’une solution et leurs interactions. Il en résulte un meilleur travail d’équipe (parallélisassions des taches), une évolutivité plus facile (nouvelle fonctionnalité = nouveau composant), une maintenance plus simple (tout changement d’implémentation d’un composant reste transparent pour les autres), …

Le couplage maîtrisé entre les modules dans ce type d’architecture est éligible à la diminution des coûts d’intégration et de maintenance d’un logiciel. L’objectif de cet article va donc être de présenter

comment développer une application web modulaire.

2.

Structure modulaire d’une application

La modularité s’applique à tous les niveaux, nous ne parlerons pas ici du niveau urbanisation et nous allons directement nous intéresser au niveau logiciel. Une application est classiquement divisée en trois couches, un composant n’appartenant qu’à une seule couche :

la couche Provider : qui contient l’ensemble des composants fournissant des services (IHM, services web, abonnement un flux de données, …),

la couche Business : qui contient l’ensemble des composants implémentant la logique métier de l’application,

la couche Consumer : qui contient l’ensemble des composants consommant des services (systèmes de persistance, services web, …).

(3)

L’approche composant permet de facilement faire évoluer les fonctionnalités d’une application. L’adjonction de plugins permet d’ajouter un ensemble de composants définissant une ou plusieurs fonctionnalités et pouvant se baser sur les composants déjà en place.

Eclipse, Atlassian (Jira, Confluence), Nuxeo, Glassfish sont des exemples de logiciels implémentant ce patron d’architecture.

La gestion des IHM dans le cas d’application modulaire peut être vue de deux manières : soit elles sont considérées comme faisant partie de la couche Provider,

soit elles font parties d’une application à part entière (approche front-end/back-end). Si on intègre les notions de multi devices ou

d’API, il semble plus cohérent de se tourner vers l’approche front-end/back-end et de voir l’application comme un fournisseur de services.

La partie front-end se base sur ces services pour la définition de l’IHM et la partie back-end se présente alors comme un composant du SI.

3.

Choix des technologies

La définition d’une solution passe par trois questions : quoi ? comment ? avec quoi ? Si l’introduction a poser la première question et le paragraphe précédent a répondu à la seconde, il nous reste à définir les outils qui vont nous permettre de développer une application web modulaire.

L’architecture orientée composant doit faciliter les échanges entre composants par l’explicitation de leur contrat d’interface. Pour assurer une réutilisabilité et une maintenance plus facile, on se rapporte systématiquement à des spécifications, lorsque celle-ci existent.

(4)

3.1.

Communication Front-end/Back-end

Dans l’approche front-end/back-end, ce n’est pas une mais deux applications que nous devons mettre en place. Ce sont, en définitive, deux composants de notre SI dont il convient de définir le protocole de communication.

En client léger, le front est hébergé par un navigateur, le langage est le JavaScript et les communications se font via l’API XMLHttpRequest spécifiée par le W3C. La mise en place d’une architecture REST semble s’imposer d’elle-même de par son utilisation du protocole HTTP et son identification des ressources par URI.

3.2.

Technologie back-end

Toute technologie permettant de faire de la programmation orienté composant (POC) est éligible pour la réalisation de l’application back-end.

D’un point de vue théorique, tous les langages objet conviennent. Des frameworks existent, permettant de faciliter l’explicitation des contrats d’interfaces et la communication entre les composants comme par exemple Spring pour Java ou MEF et Unity pour .Net. Mais ils n’imposent pas le respect de l’approche composant. Dans la durée, à cause de contraintes projet ou simplement par inadvertance, des raccourcis peuvent être pris. Au final, la maintenance et l’évolutivité seront aussi couteuses que dans une architecture qui n’est pas à base de composants.

À ce jour seule la technologie OSGI impose une approche composant et en définit les spécifications assurant une interopérabilité entre les différentes implémentations. Cette technologie, si elle ne s’impose pas, est à privilégier.

Un principe de fonctionnement d’une application web modulaire, coté back-end, consiste à disposer d’un conteneur pour un contexte web particulier dans lequel les composants pourraient déposer leurs ressources : service REST, filtre, ressource statique, … Le conteneur fait alors l’union de l’ensemble de ces ressources et les présente de manière unifiée sous le même URL.

L’ajout d’un plugin permet d’ajouter de nouvelles pages et/ou de nouveaux services REST à l’application.

En plus des avantages déjà évoqués en termes de cout de maintenance, le déploiement s’en trouve simplifié puisqu’on ne livre plus l’application entière mais seulement les plugins.

Pour ce qui est de la continuité de service, pour des opérations de maintenance, on peut également assurer le fonctionnement du reste du site pendant le retrait ou la mise à jour d’un plugin.

(5)

En pratique avec la technologie OSGI, on définit simplement un service REST en utilisant les annotations JAX-RS.

Puis on les expose sous forme de services (OSGI) d’un bundle (composant OSGI), via blueprint (Specs. R6 Entreprise §121)

3.3.

Technologie Front-end

Nous avons déjà défini que nous nous plaçons dans le cas de client léger dans un navigateur Web. Les langages utilisés sont donc : HTML, CSS et JavaScript. Mais il existe pléthore de frameworks. Il convient de faire une sélection. Pour cela utilisons l’approche composant. En effet l’application front-end est tout d’abord une application qui possède les couches Provider, Business et Consumer.

3.3.1.

Comment définir les composants de la couche Provider

Pour la couche Provider, qui va gérer l’IHM proprement dite, la notion de composant est intrinsèque puisqu’une page peut être considérée comme un composant composite. C'est-à-dire elle-même composé de composants graphiques. Il nous faut donc définir des composants graphiques, en HTML cela revient à définir des balises spécifiques dont les attributs, les propriétés et les méthodes sont spécifiés et en constituent le contrat d’interface.

(6)

L’exemple ci-dessus montre la réutilisabilité et le caractère protecteur des composants. Il est possible de les composer pour définir de nouveaux composants et ils sont développés et testés de manière autonome facilitant les aspects de maintenance.

Mais nous n’avons toujours pas répondu à la question : quel framework utiliser pour développer ces balises spécifiques ? Là encore beaucoup d’élus. J’ai testé les suivants : Angular, Knockout, Vue.js, React et tous fonctionnent parfaitement. Par contre, si on essaye de mélanger des balises développées avec un framework avec les balises d’un autre framework dans ce cas plus aucun de ces frameworks ne fonctionnent. Et c’est là que le bât blesse. Dans une architecture orientée composant, les communications se basent sur les contrats d’interface indépendamment des implémentations. Cet aspect est crucial pour la maintenabilité de nos applications. Prenons le cas d’une application contenant un millier d’écrans et développée avec, par exemple, l’Angular de 2016 et projetons-nous dans cinq ans. L’expérience démontre que la version de 2022 sera probablement incompatible avec vos développements. Comment faire évoluer votre application ?

Il ne reste que trois choix :

continuer à développer dans une version obsolète, cette solution alourdira votre dette technique redévelopper avec un nouveau framework avec l’ensemble des coûts afférents (migration des pages à faire évoluer)

mettre à jour l’ensemble de vos pages avec la nouvelle version, ce qui même à concurrence de 2h par page nous amène à des coûts exorbitants si le nombre de pages est important

Aucune de ses solutions n’est satisfaisante, il nous faut donc éliminer l’approche par balises spécifiques gérés par un seul framework.

Heureusement, le W3C a défini une spécification pour les customs elements, et cette spécification est supportée par l’ensemble des navigateurs (via la mise en place de polyfills pour certains d’entre eux). Ce qui va dans le sens des règles énoncées en début de ce chapitre, à savoir « on se rapporte systématiquement à des spécifications lorsque celle-ci existent ».

La définition de ces customs elements est extrêmement simple par le chainage du prototype HTMLElement.

C’est dans l’implémentation des fonctions connectedCallback, disconnectedCallback et attributeChangedCallback, de l’interface HTMLElement, que vont pouvoir intervenir les frameworks

(7)

pour assurer le binding Javascript HTML. On s’assure alors de l’interopérabilité de nos customs elements, qu’ils soient développés ou non en utilisant le même framework.

Voici un exemple d’implémentation (TypeScript) en utilisant Vue.js.

C’est dans l’implémentation de connectedCallback, appelée lorsque la balise est insérée dans le DOM, que l’on utilise Vue.js.

On notera l’utilisation d’un template externe pour respecter le patron de « separation of concerns » entre la vue et le vue-modèle. (Vue.js étant un framework MVVM).

Cette approche peut être utilisée avec tous les frameworks ayant une architecture modulaire, je l’ai testée également avec Knockout et DHTMLX.

Les recherches que j’ai pu faire me permettent d’affirmer que React est également éligible, et dans une moindre mesure AngularJS. Le paragraphe suivant nous en expliquera les raisons.

Auparavant, en conclusion intermédiaire, l’utilisation des customs elements (W3C), nous assure l’indépendance vis-à-vis des frameworks ce qui nous permet :

d’ajouter des fonctionnalités à nos applications en utilisant un nouveau framework,

de faire migrer progressivement l’existant (un custom element à la fois), évitant ainsi l’effet big-bang.

3.3.2.

Éligibilité des frameworks JavaScript

Dans le paragraphe précédent, j’ai énoncé que tous les frameworks modulaires sont éligibles. Il convient de détailler ce critère.

La gestion d’un site en JavaScript nécessite la mise en place de plusieurs fonctionnalité, le binding HTML JavaScript énoncé dans le paragraphe précédent n’en est qu’un parmi d’autre. Il faut également gérer : le routage, les clients des services REST, un outil de publish/subscribe, …

Dans une architecture modulaire, un framework peut implémenter plusieurs fonctionnalités mais il ne doit pas dépendre de sa propre implémentation et pouvoir utiliser celle d’un autre composant. Prenons l’exemple du routage, cette fonctionnalité est utilisée pour la navigation dans les SPA (Single Page Application).

Avant toute chose, comme pour les customs elements, il convient de définir le contrat d’interface de cette fonctionnalité. L’interface Router, en TypeScript, présentée ci-contre en est un exemple.

(8)

À partir de là, tout framework voulant exposer la fonctionnalité de router doit respecter cette interface (un simple wrapper permet une adaptation facile) et tout framework voulant utiliser cette fonctionnalité doit utiliser cette interface.

Donc si une framework ne peut pas isoler ces fonctionnalités, il n’est donc pas modulaire il ne peut donc pas être éligible. EmberJs en est un très bon exemple, ce framework se base sur son propre router et il gère également les fonctionnalités de binding. Les deux fonctionnalités sont indissociables, ce framework n’est donc pas modulaire, il n’est pas éligible selon nos critères sans grever fortement la maintenabilité de notre application.

Dans le paragraphe précédent, j’ai émis des réserves quant à l’éligibilité d’AngularJS. En pratique, il est possible d’isoler sa fonctionnalité de binding, mais l’effort est très important et dégrade fortement l’intérêt du framework.

3.3.3.

Du JavaScript, oui mais quel JavaScript ?

Jusqu’à présent nous avons parlé de framework JavaScript, mais il existe plusieurs versions de JavaScript laquelle choisir ?

L’ECMAScript 5 est en fin de vie mais c’est le seul langage entièrement supporté par tous les navigateurs. Pour les versions ECMA201x, on peut alors utiliser des outils de type Babel lors du build pour assurer le transpilage vers l’ECMAScript5. Cela nous permet de développer dans la dernière version (ECMA2017 à ce jour) et d’attendre que les navigateurs supportent cette version pour supprimer cette étape de build.

Une autre solution est d’utiliser le TypeScript.

Dans un premier temps, j’étais contre l’utilisation de ce langage. Développer en TypeScript pour générer du JavaScript me semble être une hérésie, pourquoi ne pas directement développer en JavaScript ? Le transpilage ne peut apporter que des problèmes pour arriver à générer ce que l’on veut vraiment obtenir. Sur ce point, la suite vous montrera que j’avais raison.

Mais si on prend un peu de recul, il se peut que dans 5 ans on en soit à l’ECMA2022 et le code produit aujourd’hui deviendra obsolète. Il sera alors surement possible de transpiler notre TypeScript vers cette nouvelle mouture de JavaScript. Cet argument l’emportant sur ma première réticence et la découverte des decorators (utile pour la productivité) m’ont fait pencher pour l’adoption de

TypeScript.

4.

L’enfer du packaging

Le développement d’applications web à base de Web component en TypeScript va nécessiter de faire du transpilage pour générer du JavaScript compréhensible par les navigateurs et de regrouper le

code des différents Web components. En effet si pour un web component on a deux fichiers (template

+ controller/vueModel) alors l’affichage d’un page va nécessiter le téléchargement de plusieurs dizaines de fichiers (il faut également compter les images et les CSS). Cela va générer des temps d’affichage pouvant dépasser les 10 secondes dans certains cas.

(9)

4.1.

Le tout en un

Il nous faut donc trouver un outil de build permettant de réaliser ces deux tâches. Après quelques recherches, Webpack 2 semble l’outil tout désigné pour réaliser cette tâche. Il dispose de ‘loader’ permettant de traiter les différents fichiers.

La configuration présentée est censée permettre de packager en un seul fichier JavaScript ES5 notre code. Mais il s’avère que la classe HTMLElement est un peu particulière et nécessite la mise en place de polyfill pour que le transpilage soit fonctionnel.

L’utilisation d’un loader Babel permet de facilement régler le problème. Le premier écueil dû au transpilage TypeScript JavaScript a ainsi été évité.

La configuration ci-après est pleinement fonctionnelle.

(10)

4.2.

Utilisation d’un CDN

L’intérêt de l’approche modulaire est la réutilisabilité de ses composants, ils ont pour but d’être utilisés non seulement dans plusieurs pages mais aussi dans plusieurs applications. Les packager dans chacune des applications n’est pas une solution satisfaisante en terme de maintenance car une correction sur un composant nécessite le redéploiement de toutes les applications qui l’utilise.

4.2.1.

Principe de mutualisation des composants

Coté back-end ce problème est déjà résolu grâce à l’OSGI car un composant, par exemple de la couche Business, peut être utilisé par autant d’application que nécessaire et sa mise à jour peut se faire de manière unitaire sans avoir à redéployer ni arrêter les applications qui l’utilisent. Il nous faut trouver une approche similaire pour le front-end, c’est là qu’intervient l’utilisation d’un CDN.

Il a pour fonction de fournir les composants aux différentes applications qui en ont besoin.

On remarque sur le schéma que tous les composants ne sont pas systématiquement réutilisables, certains peuvent êtres spécifiques à une application et donc fournis directement par celle-ci.

4.2.2.

Prise en compte du CDN dans le packaging

Dans le paragraphe ‘Le tout en un’, nous avons utilisé Webpack pour le build de notre projet. Il nous faut maintenant lui indiquer que certain des composants ne font pas partie du projet et doivent être directement récupérés depuis le CDN (en paramétrant si possible la location du CDN) au moment du runtime.

Malheureusement Webpack n’en est pas capable car il n’a tout simplement pas été développé dans ce but.

En effet, Webpack identifie tous les modules (au sens JavaScript) de notre développement en créant un tableau et assure l’injection de dépendances entre modules en se basant sur leur index dans ce tableau. Un module externe n’étant pas recensé, il ne peut être injecté.

(11)

La notion d’injection de dépendance va être le nœud du problème. Non seulement les composants peuvent se trouver sur un CDN mais en plus un fichier sur le CDN peut contenir plusieurs composants pour éviter la problématique des téléchargements multiples énoncée au début de ce chapitre. Pour que cela puissent fonctionner, il faut que l’on puisse désigner les composants non seulement par leur localisation mais aussi par un identifiant.

Il existe 3 méthodes, issues de spécifications, permettant de gérer les dépendances entre modules : AMD, CommonJS et la directive import (ES2015). Et il va nous falloir des modules loader spécifiques pour définir la manière de charger nos dépendances. Cette notion de modules loader n’existe pas en ES2015 et est à l’état de proposition pour CommonJS. La seule option restante est donc AMD.

Il nous suffit d’implémenter les modules loader cdn et pack pour répondre au besoin. Ce qui est relativement simple en utilisant l’implémentation RequireJS. Ce choix n’est pas totalement innocent car RequireJS possède un optimiseur qui va nous être utile lors du packaging.

Les syntaxes que l’on obtient sont :

module jquery@1.2.3.js depuis le cdn

module jquery depuis le package util.js

module jquery depuis le package util.js sur le cdn

Mais ce n’est que le JavaScript que l’on veut obtenir, rappelons que nous avons décidé de développer en TypeScript. Les dépendances se font uniquement via la directive import.

Il n’est pas souhaitable à ce moment-là de spécifier où se trouve la dépendance car c’est du ressort du build et nous devons pouvoir changer la localisation en fonction des environnements (développement, production, …). On rentre alors de plein pied dans les inconvénients du transpilage, et les réticences que j’avais émises se trouvent complétement justifiées.

Le tableau n’est quand même pas aussi noir que ce qu’il paraît. On a prouvé que le transpilage du TypeScript en ECMAScript ES2107 marche bien et celui de ECMAScript ES2017 en JavaScript via babel fonctionne également très bien. Il nous suffirait entre ces deux étapes de modifier les chemins d’import (Ex : import * as $ from ‘jquery’ import * as $ from ‘cdn!jquery’) pour faire le job.

La prochaine étape est donc de trouver le bon outil de build.

4.3.

Choix d’un outil de build

Je vous rassure tout de suite, il n’existe pas d’outil aussi avancé que Webpack pour réaliser notre build. On cherche donc un outil fortement paramétrable et évolutif, dans le monde du JavaScript il en existe

(12)

deux principaux Grunt et Gulp. Personnellement je ne trouve pas que l’un soit meilleur que l’autre, j’ai donc arbitrairement choisi d’utilisé Gulp.

On le configure pour générer : de l’ECMAScript 2017,

des modules UMD (compatibles avec CommonJS et AMD)

Et on définit la localisation de nos bundles.

Il n’y a plus qu’à définir la tâche de transpilage :

On remarque que l’on a comme dépendance une tache de compilation (« compile ») car il faut s’assurer que le code compile avant de le modifier. On remplace ensuite les imports (CSS, HTML, Localisation) en fonction des modules loaders que l’on veut activer puis on lance le transpilage, en ECMA2017 puis en ES5 via babel.

Pour le packaging permettant de regrouper les fichiers, j’utilise une version personnalisée du plugin gulp-requirejs-bundler qui permet de spécifier finement les composants que je désire regrouper.

Le résultat est celui attendu : 3 fichiers main.js, page1.js et page2.js. Le fichier main incluant toutes les dépendances communes au site et appelant en just in time, les packages des pages 1 et deux qui contiennent leur code et celui des composants qu’elles incluent.

(13)

5.

Et les couches Business et Consumer du front-end dans tout

ça ?

Pour l’instant nous nous sommes intéressés à la couche Provider du front-end, pour essayer de trouver une approche permettant de nous décorréler des frameworks pour l’implémentation des Web components.

Si nous reprenons le schéma standard d’une application modulaire, il en va de même pour les autres couches. Il va donc falloir définir des contrats d’interface pour chacun de nos composants. Et les communications ne pourront se faire qu’au travers ces interfaces.

Cette approche est en fait utilisée systématiquement dans les développements

back-end (qui n’a pas défini une interface pour accéder à un DAO ?). Il est étonnant qu’elle ne soit pas systématiquement utilisée dans les développements front-end (si ce n’est la volonté de vouloir produire le plus rapidement possible, l’introduction a démontré que c’est une approche la plus couteuse au final que l’approche composant).

L’injection directe de dépendance n’est alors plus possible. Car c’est une approche déterministe, avec l’AMD, CommonJS ou les imports on spécifie l’implémentation (~le fichier JS) que l’on veut utiliser. Un changement de l’implémentation d’une interface oblige à modifier tous les composants qui en dépendent. L’approche correcte est de sélectionner/filtrer automatiquement le composant exposant l’interface souhaité. C’est exactement le fonctionnement de Spring (@Autowired), de CDI (@Inject) ou de l’OSGI (ServiceTracker).

(14)

Il nous faut donc mettre à disposition un registre de service. La notion d’interface en Javascript n’existant pas il nous faut également un registre d’API. L’objectif est qu’un composant s’inscrive auprès du registre de service comme implémentant une ou plusieurs API.

Ce code donne un exemple de déclaration de l’API de publish/subscribe. Vous noterez que cette description donne la liste des méthodes (subscribe, publish) ainsi que leur signature, paramètres et valeur de retour (via JSON Schema).

Cette description est nécessaire car l’enregistrement des services se fait au runtime. Et il faut valider qu’ils implémentent bien l’API déclarée.

On pourrait penser que l’utilisation des interfaces TypeScript pourrait pallier à cette vérification, mais dans ce cas la validation se fait au build

time.

L’enregistrement d’un service se fait simplement en précisant l’implémentation choisie (Ici un exemple utilisant la librairie PubSub).

Ce principe peut être utilisé pour exposer n’importe quel service de nos composants.

Le référencement du service se fait uniquement en précisant l’API désirée Le registre de service fournit alors l’implémentation correspondante.

(15)

5.2.

Versionning et filtrage

Vous l’avez peut-être remarqué mais dans l’exemple de déclaration de service du paragraphe précédent, nous n’avons pas seulement précisé l’API :

Il faut également définir la version de l’API et les propriétés (facultatives) du service. Les utilisateurs d’OSGI sont familiers avec cette pratique, car elle est indispensable pour la maintenance des applications.

Le filtrage sert lorsque plusieurs composants exposent la même API. Envisageons une API CRUD, les propriétés permettent de spécifier sur quelle entité s’applique le service CRUD exposée.

Quand on parle de versionning, il s’agit obligatoirement de versionning sémantique et on doit pouvoir

préciser lors du référencement service un intervalle de versions.

Il est important pour les versions mineures de s’assurer que l’implémentation du service contient bien toutes les fonctionnalités attendues et pour les versions majeures qu’il y a bien compatibilité avec le composant que vous être en train de développer.

Il n’est pas commun, d’avoir au sein d’une même application plusieurs versions d’un même service et donc plusieurs versions de la même interface, pourtant ce cas arrive fréquemment.

Mettons-nous dans le contexte d’une application gérant la gestion d’identité dans votre SI. Elle propose pour toutes les autres applications des services REST pour faire la recherche et la mise à jour des utilisateurs.

Et elle propose également les composants client (couche Consumer) pour que les applications puissent facilement interroger ces services. Ces composants sont mis à disposition via le CDN. Et ces composants sont utilisés dans différentes pages de différentes applications.

Lorsque l’application de gestion des identités évolue, elle peut faire évoluer son API en V2 (non compatible V1). Les composants clients en place ne sont plus compatibles. On pourrait penser qu’il suffit de déployer sur le CDN la nouvelle version des composants client pour que tout fonctionne automatiquement. Mais ces derniers exposent, au sein des applications 1 & 2, une API en correspondance avec l’API REST. La nouvelle version des composants clients n’est alors pas compatible avec les composants de la couche business.

(16)

La solution de modifier l’ensemble des composants de la couche business est inenvisageable pour des questions de coût. Il nous faut donc trouver une solution permettant aux anciens développements de fonctionner (compatible V1) et au nouveau développement de pouvoir prendre en compte la nouvelle API (V2). Nous aurons ainsi inévitablement au sein de notre application deux versions de la même API. Une alternative serait de faire évoluer les

composants client V1, en une version V1.1, qui fait l’adaptation des appels de l’API cliente V1 vers l’API REST V2.

Ces composants étant sur le CDN, ils sont automatiquement pris en compte par l’ensemble des applications et le coût de maintenance est réduit à son minimum.

Les nouveaux développements peuvent utiliser la dernière version de l’API REST. La migration

complète vers cette version peut se faire au rythme des cycles de vie des différentes applications. Une démarche similaire peut-être envisagée au sein d’une même application quand le nombre d’écrans ou de composants impactés engendre des coûts de maintenance évolutive importants.

6.

Conclusion

Cet article a défini une solution permettant de développer des applications entièrement modulaires. Si la partie back-end reste dans les standards actuels de développement, la partie front-end propose une nouvelle manière de développer nos frontaux web.

La tendance actuelle est d’utiliser les derniers frameworks éprouvés. Cela revient pour le choix des technologies de répondre à la question avec quoi (cf. §Choix des technologies) sans réellement envisager le comment.

Il est évident que la solution proposée implique un coût de développement initial supérieur, ne serait-ce que pour la définition des API. Mais elle assure un coût global largement inférieur.

Cette solution n’est évidemment pas une silver bullet, si votre besoin est le développement d’un frontal web :

de quelques pages,

n’ayant pas besoin de réutiliser des composants existants,

ne fournissant pas de fonctionnalités réutilisables par d’autres applications, n’étant pas destiné à évoluer fonctionnellement.

Alors cette approche n’est pas forcement la plus rentable. Dans les autres cas, elle assure une diminution du coût du cycle de vie de vos applications et de votre SI.

Références

Documents relatifs

As avaliações foram realizadas diariamente, obtendo-se o IVG (Índice de Velocidade de e ao final do experimento obteve-se a porcentagem de germinação,

We have used an 880 LW AGEMA infrared camera (connected to real time software) in order to measure external and internal preform surface temperature distribution, heat

Si on se limite aux jeunes non incorporés qui ont répondu à la fois au premier et au deuxième questionnaire, la différence de taux d’emploi avec les jeunes incorporés

In this paper, we use a game-theoretic model to highlight coordination failure that hinder the emergence of networks. of female entrepreneurs necessary to

Findings further indicate that although industrial design practice in Alberta remains underdeveloped compared to Québec and Ontario, with increased government support,

Entre 1995 et 2009, deux pays ont vu leur contribution à l’encours de dette total de la zone euro significativement augmenter : ce sont les Pays-Bas et l’Espagne en raison

Le taux de chômage a continué sa progres- sion, atteignant un point haut à 12,9 % de la population active en janvier 2014, mais sans avoir d’influence sur les salaires, avec

Pour autant, nous excluons l’hypothèse d’un resserrement de la politique monétaire par le biais d’une hausse des taux d’intérêt directeur car la croissance reste fragile,