P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ RTFM Articles | Connexion
 
~Builder

 Présentation

Cela fait 6 cours que l'on vous présente les modèles de conception réutilisables. Notre étude a éclairci l'utilisation de quelque dix modèles. Les adeptes de la conception objet seront donc ravis de constater que beaucoup de choses restent à découvrir.
 Sommaire


 Le motif Builder

L'intention du motif Builder, ou monteur en français, concerne la dissociation d'un objet complexe de sa représentation. Cette dissociation apparaît de telle sorte que le même processus de construction engendre différentes représentations.

Parmi les nombreuses situations susceptibles de justifier l'implémentation d'un tel motif, une se révèle particulièrement parlante : un convertisseur de documents. Un lecteur de documents pour un format d'échange fictif (nous employons ici un format propriétaire intitulé SD pour Stylized Documents) se destine à convertir un document SD en d'autres formats de textes. Notre outil pourra par exemple générer des documents LaTeX, HTML, RTF ou tout simplement du texte brut.

La conception d'un tel outil peut conduire à réaliser une classe principale employant la classe Convertisseur. Une classe Convertisseur reçoit les données SD brutes et les transforme conformément au format de destination. Ainsi, un convertisseur joue deux rôles : celui de traduire, si besoin est, les données (par exemple encoder les accents en UTF-8) et celui de représenter lesdites données.



Nous pouvons également créer le rendu d'un fichier HTML.


 Les fichiers SD

A cet égard, l'application comprendra un lecteur de documents qui émettra des requêtes vers le convertisseur à chaque entité de format rencontrée. Une entité désigne une instruction, un bloc de texte. Ainsi un convertisseur de documents HTML traitera les balises comme des entités de type instruction. Le listing numéro un propose un exemple de document SD que notre application Python saura traiter.

Notre format exploite deux types d'entités : les instructions, délimitées par des accolades, et les blocs de textes, marqués par les crochets. Certaines instructions s'appliquent sur l'ensemble d'un bloc de texte. Ainsi, l'extrait {bold}[mot] sera traduit en HTML de cette façon : mot. A l'instar de HTML, notre format exploite des instructions de style (gras, italique.) et de mise en page (saut de ligne, indentation.). De cette manière, un convertisseur de fichiers SD vers un format de texte brut ne prendra en compte que certaines instructions.

L'application proposée dans le fichier zip d'annexe a été rédigée en Python et supporte la conversion de documents SD en HTML ou en texte brut. Le démarrage du processus de conversion se réalise par l'entremise de l'une des commandes suivantes :

processor.py html document.sd
processor.py txt document.sd
       
      
JextCopier dans Jext | Jext | Plugin Codegeek


Analyse du monteur.


 Implémentation du motif Builder

Notre application nécessite la création de deux classes de conversion : une classe dédiée au HTML et une classe dédiée au texte. Ces deux classes dérivent de la classe Builder et sont désignées sous le terme de monteurs. Au sein du listing numéro deux se trouve la définition de la classe abstraite Builder. Nos deux classes de conversion devront hériter de cette dernière. Ainsi, chaque type de classe convertisseur prend en charge le mécanisme de création et d'assemblage d'un objet complexe placé en aval d'une interface abstraite. Ici, l'interface se voit définie par la classe Builder. Le convertisseur se voit finalement séparé du lecteur chargé de l'analyse syntaxique.

Chaque sous-classe du monteur implémentera à sa guise les méthodes abstraites proposées. Ainsi, pour le traitement des instructions lors de la conversion d'un document SD en texte brut, notre programme emploiera les instructions suivantes :

def instruction(self, keyword):
  if keyword == "indent":
    self.f.write("\t");
  elif keyword == "break":
    self.f.write("\n");
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Vous pouvez constater que seules les instructions de mise en page sont traitées. Pour concrétiser la mise en place de nos monteurs, notre application doit ensuite proposer un directeur, une classe destinée à adresser des requêtes aux monteurs. Dans le cadre de notre lecteur, le directeur s'incarne sous la forme d'une classe intitulée Director. Lors de sa construction, le directeur récupère une instance du monteur qui sera exploité lors de l'analyse syntaxique. Voici ce qu'il se passe lorsque le directeur a détecté une instruction :

if c == '}':
  self.builder.instruction(buffer)
       
      
JextCopier dans Jext
La hiérarchie finale des classes se révèle relativement simple tant les relations sont linéaires. L'exemple proposé ici met en place une séparation entre l'algorithme interpréteur du format SD et le mécanisme de représentation. L'algorithme d'interprétation peut alors être très facilement réutilisé. En outre, l'ajout de nouveaux formats de conversion ne nécessite que la création d'un nouveau monteur.


 Choix du monteur

Le choix du monteur le plus approprié au traitement pose encore problème. Pourtant, les motifs de conception sont là pour apporter une solution simple et efficace à ce problème. Parmi les premiers design patterns exploités dans cette rubrique se trouve un motif intitulé Fabrique. Son comportement consiste en la sélection de la sous-classe la plus appropriée en fonction d'un paramètre. Notre exemple concernant la fabrique traitait d'une situation dans laquelle un fichier pouvait se voir ouvert sur le disque dur ou depuis un serveur HTTP. La sélection s'opérait en fonction du préfixe du nom de fichier (la mention "http://" marquait l'ouverture d'un fichier sur un serveur). Le lecteur de documents SD présenté base sa sélection sur le premier paramètre donnée à l'application. Le listing numéro trois présente une fabrique destinée à la sélection du monteur.

Si la valeur du paramètre est "html" la fabrique renvoie une instance du monteur HTML. Si le paramètre vaut "txt" ou toute autre valeur, un monteur texte se voit créé. L'exécution du processus de conversion pourra enfin se voir réalisée en rédigeant quelques instructions :

factory = Factory()
doc = Director(factory.getBuilder(sys.argv[1]))
doc.convert(sys.argv[2])
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le choix du langage Python ne met pas en avant le caractère statique de la méthode getBuilder() de la fabrique. De même, l'abstraction de la classe Builder et de ses méthodes ne se voit pas soulignée. L'exemple proposé met en avant un mélange de design patterns et démontre leur viabilité en environnement de production. Pour maîtriser le concept du motif Builder, vous pouvez implémenter de nouveaux monteurs. La réalisation d'un monteur de conversion au format TeX ne devrait pas poser de problèmes particuliers.


 Annexes


Listing 1 :

{bold}[Stylized Documents]{break}{break}
{indent}[Ceci est un exemple simple.
Voici du texte en ]{red}[rouge][.]{break}
[Notre exemple de processeur écrit en Python doit ]{italic}[pouvoir]
[ générer du texte]{break}
[et de l'HTML depuis ce document à la syntaxe ]{underline}[affreuse][.]
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Listing 2 :

class Builder:
  def open(self, filename):
    self.f = open(filename, "w")
  def close(self):
    self.f.close()
  def instruction(self, keyword):
    pass
  def text(self, str):
    pass
  def getExtension(self):
    return ""
       
      
JextCopier dans Jext
Listing 3 :

class Factory:
  def getBuilder(self, mode):
    if mode == "html":
      return HTMLBuilder()
    elif mode == "txt":
      return TextBuilder()
    else:
      return TextBuilder()
       
      
JextCopier dans Jext


par Romain Guy
romain.guy@jext.org
http://www.jext.org
Dernière mise à jour : 14/10/2006



 
#ProgX©2005 Mathieu GINOD - Romain GUY - Erik LOUISE