Qu’est-ce qu’un wrapper en programmation ?
En anglais, le terme « wrapper » désigne entre autres un papier d’emballage ou une jaquette de livre. Dans le domaine informatique, le terme désigne un programme ou code qui « enveloppe », ou englobe, d’autres composants logiciels. Plusieurs raisons motivent le recours aux wrappers.
La compatibilité et l’interopérabilité entre des structures logicielles hétérogènes en sont une et la représentation visuelle une autre, à l’image des wrappers HTML et CSS. Un wrapper peut s’appliquer à un composant logiciel, un produit logiciel indépendant, une architecture logicielle, une classe en programmation orientée objet ou un framework.
Si un programme inclut des fonctions ou blocs écrits dans un autre langage de programmation, on peut les envelopper à l’aide d’un wrapper. Le programme principal communique exclusivement avec le wrapper, qui transmet les instructions à la partie enveloppée du programme et renvoie les résultats. Le wrapper est le seul composant qui communique directement avec les deux parties du programme.
Les wrappers ont de multiples usages en programmation et en développement logiciel. Les exemples d’application suivants montrent comment fonctionne un wrapper et les tâches qu’il peut réaliser.
Le wrapper pour convertir des saisies d’utilisateur
Les formulaires présents dans les programmes ou applications Web requièrent la saisie de données pouvant être traitées par le programme. Dans le monde anglo-saxon, on tient parfois pour acquis que les chiffres s’écrivent et doivent être saisis avec un point pour séparer les décimales (au lieu d’une virgule) et les dimensions en pieds et en pouces.
Or, quand on utilise ce genre de composant dans ses propres applications, il n’est pas toujours possible de les adapter aux spécificités d’écriture locales, ce qui aboutit inévitablement à des résultats erronés, voire des bugs.
Dans ces cas-là, un wrapper peut s’avérer utile. Le formulaire de saisie ne transmet pas les saisies directement au programme externe, mais au wrapper. Celui-ci examine les saisies et les convertit en saisies valides pour le programme externe sans que ce dernier n’ait besoin d’être modifié.
Le wrapper pour accéder à des bases de données
Les bases de données de fournisseurs différents sont généralement difficiles à utiliser ensemble, puisque les tables de données, requêtes et langages de requête ne sont pas compatibles. Là encore, un wrapper peut être la solution. Comme dans n’importe quel type de wrapper, l’idée est de repérer les incohérences entre des interfaces logicielles différentes et de les pallier avec le wrapper.
L’interface Java Database Connectivity (JDBC), qui est une interface de base de données de la plateforme Oracle Java, est un exemple type de wrapper. JDBC permet, quand elle est utilisée comme fonction wrapper, d’accéder à des bases de données relationnelles de fournisseurs logiciels différents. Elle établit une liaison avec les bases de données au moyen de pilotes spéciaux.
Les requêtes SQL des programmes sont adressées à JDBC et non aux bases de données elles-mêmes. JDBC convertit les requêtes dans le langage d’interrogation employé par la base de données concernée et renvoie le résultat dans un format compatible avec Java. De cette manière, le programme à l’origine de la requête reçoit systématiquement les données dans un même format, indépendamment de la base de données utilisée.
Le wrapper en programmation orientée objet
En programmation orientée objet, on fait appel à des patrons de structure, qui fonctionnent de manière identique quel que soit le langage utilisé. Les patrons de conception adaptateur et décorateur entrent dans la catégorie de ces patrons de structure et sont considérés comme des wrappers.
Un adaptateur enclave des interfaces mutuellement incompatibles entre des classes différentes. En convertissant une interface en une autre, les classes peuvent à nouveau échanger entre elles. C’est très utile lorsque des classes ou des bibliothèques de classes entières doivent être réutilisées dans de nouveaux projets. Ces bibliothèques emploient des interfaces standardisées distinctes qui ne peuvent pas être modifiées, car elles doivent être valables pour une multitude de programmes. Le wrapper (ici l’adaptateur) agit comme un intermédiaire décisif dans la communication.
Un décorateur permet d’enrichir une classe de fonctions supplémentaires sans la modifier. Le décorateur a, par rapport à l’objet appelant, la même interface que la classe d’origine. De fait, il n’y a rien à modifier dans l’objet appelant. Le décorateur, en tant que wrapper, transmet les appels à la classe. Il exécute directement les nouvelles fonctions qui ne sont pas contenues dans la classe. Enfin, il renvoie les résultats de telle sorte que ceux-ci apparaissent à l’objet appelant comme des résultats de la classe décorée.
Le wrapper pour concevoir des documents HTML
Les wrappers sont fréquemment utilisés dans la conception (et la refonte) de sites Web en HTML et CSS. Sans eux, pour effectuer certaines modifications, par exemple pour modifier la taille des marges, il faudrait modifier plusieurs feuilles de style en veillant simultanément à ce qu’elles coïncident.
Il est plus simple de placer un wrapper sous forme de conteneur DIV autour du contenu entier de la page, comme dans l’exemple suivant :
<html>
<head>
...
</head>
<body>
<div class="wrapper">
…
</div>
</body>
</html>
Le contenu réel de la page se trouve alors à l’intérieur du conteneur wrapper.
Les propriétés du wrapper sont définies dans le fichier CSS lié :
body {
margin: 0;
padding: 0
}
.wrapper {
width: 500px;
margin: 25px auto;
}
Dans cet exemple, on attribue une largeur de 500 pixels au conteneur via la propriété width:. Les marges en haut et en bas sont définies à 25 pixels via la propriété margin:. Les marges à gauche et à droite découlent automatiquement de la largeur de la fenêtre de navigateur et de la largeur du conteneur.
Par une modification simple du wrapper, il est possible d’adapter facilement les marges sans toucher davantage au code HTML ou CSS.
Wrapper TCP dans les systèmes Linux
Le service d’arrière-plan inetd, que l’on trouve sur Linux et d’autres systèmes d’exploitation basés sur UNIX, s’exécute comme wrapper TCP. inetd écoute les connecteurs (sockets) réseau et accepte les demandes de connexion. Un fichier de configuration définit les ports qui doivent être surveillés. Les demandes sont examinées et le service inetd indiqué dans le fichier de configuration est démarré pour le port concerné. Le plus souvent, ces programmes sont des daemons qui tournent en arrière-plan.
Une fois la connexion terminée, inetd met fin automatiquement au service démarré. Le démarrage à la demande fait économiser des ressources système par rapport au démarrage automatique de services réseau éventuellement pas utiles du tout. inetd fonctionne comme un wrapper auquel tous les programmes adressent leurs demandes réseau sans communiquer directement avec les services individuels.
Les wrappers TCP peuvent aussi servir à empêcher des accès indésirables provenant d’un réseau. Le wrapper TCP est alors appelé par inetd ou par un logiciel de serveur spécial. Les hôtes et ordinateurs autorisés et interdits sont inscrits dans les fichiers /etc/hosts.allow et /etc/hosts.deny.