<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Laumaillé.net</title>
	<atom:link href="http://www.laumaille.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.laumaille.net</link>
	<description>Web Design, Design Patterns, Technologies .Net...</description>
	<pubDate>Fri, 11 Apr 2008 16:20:35 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>fr</language>
			<item>
		<title>Différences de syntaxe VB.Net - C#</title>
		<link>http://www.laumaille.net/2008/03/28/differences-de-syntaxe-vbnet-c/</link>
		<comments>http://www.laumaille.net/2008/03/28/differences-de-syntaxe-vbnet-c/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 11:16:12 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[.Net]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2008/03/28/differences-de-syntaxe-vbnet-c/</guid>
		<description><![CDATA[J&#8217;ai parfois cherché des tableaux montrant quelques différences de syntaxe essentielles entre VB.Net et C#, et je n&#8217;ai jamais vraiment trouvé de quoi me satisfaire pleinement&#8230;
Du coup, au grand mot les grands remèdes, en ce moment, je me mets à fond sur le C#, histoire de bien comprendre la syntaxe, et je compile petit à [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;ai parfois cherché des tableaux montrant quelques différences de syntaxe essentielles entre VB.Net et C#, et je n&#8217;ai jamais vraiment trouvé de quoi me satisfaire pleinement&#8230;</p>
<p>Du coup, au grand mot les grands remèdes, en ce moment, je me mets à fond sur le C#, histoire de bien comprendre la syntaxe, et je compile petit à petit un tableau de ce qui me semble essentiel à savoir. En effet, qui n&#8217;est jamais tombé dans quelques pièges dus à des mots réservés qui, même s&#8217;ils existent dans les deux langages, ne veulent pas obligatoirement dire la même chose ? <img src='http://www.laumaille.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Allez, pour vous et rien que pour vous, voici <a href="http://www.laumaille.net/?page_id=38" title="Différences de syntaxe VB.Net - C#"><strong>MON</strong> tableau</a> à moi des différences notables et souvent secourables entre les deux langages majeurs du Framework !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2008/03/28/differences-de-syntaxe-vbnet-c/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Evaluation/Exécution d&#8217;une chaine</title>
		<link>http://www.laumaille.net/2007/12/19/evaluationexecution-dune-chaine/</link>
		<comments>http://www.laumaille.net/2007/12/19/evaluationexecution-dune-chaine/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 15:15:58 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[.Net]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/12/19/evaluationexecution-dune-chaine/</guid>
		<description><![CDATA[Petit article présentant comment évaluer/exécuter une chaine de caractères comme un morceau de code. Cette technique peut être utile, par exemple, si vous voulez coder une application dont certaines parties du code sont stockées en base de données. Cela vous permet donc de créer une application qui sera ensuite &#8220;extensible&#8221; (dans une certaine mesure&#8230;) via [...]]]></description>
			<content:encoded><![CDATA[<p>Petit article présentant comment évaluer/exécuter une chaine de caractères comme un morceau de code. Cette technique peut être utile, par exemple, si vous voulez coder une application dont certaines parties du code sont stockées en base de données. Cela vous permet donc de créer une application qui sera ensuite &#8220;extensible&#8221; (dans une certaine mesure&#8230;) via des mises à jour de la base de données.</p>
<p>Pas convaincu ? Un exemple un peu plus concret vous aiderait ? Ok, en voilà un parmis tant d&#8217;autres&#8230;</p>
<p>Imaginez une application de dessin. Dans votre barre de menu, entre autre, vous retrouvez un menu &#8220;Transformation&#8221;, qui permet d&#8217;effectuer différents traitements sur votre image tels que la rotation à 90° à droite, ou l&#8217;inversion des couleurs. Quelque chose de ce style, quoi :</p>
<p><img src="http://www.laumaille.net/wp-content/uploads/2007/12/evalchaineexempleinterface.png" alt="Exemple d’interface - Evaluation de chaine" /></p>
<p>Que diriez-vous de pouvoir augmenter les options de ce menu par la suite en mettant simplement une table à jour dans votre base de données, décrivant le nom de la commande et le code à exécuter ?</p>
<p><span id="more-36"></span></p>
<p>Et bien la méthode à utiliser est somme toute assez simple, mais quand on ne la connait pas, et bien&#8230; Ça ne s&#8217;invente pas !</p>
<p>Reprenons l&#8217;exemple de notre application de dessin. On peut raisonnablement estimer que pour chaque commande correspondant au menu transformation, la fonction qui exécutera le code correspondant devra prendre une image en argument, et renvoyer l&#8217;image transformée. On peut donc définir une partie du code de notre application (je n&#8217;expliquerai pas les parties de connexion à la base de données) :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Private</span> _img <span style="color: #FF8000;">As</span> Image
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #FF8000;">Property</span> Image<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Image
    <span style="color: #FF8000;">Get</span>
        Return <span style="color: #FF8000;">Me</span>._img
    <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Get</span>
    <span style="color: #FF8000;">Set</span><span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> value <span style="color: #FF8000;">As</span> Image<span style="color: #000000;">&#41;</span>
        <span style="color: #FF8000;">Me</span>._img = Image
    <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Set</span>
<span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Property</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">' Requis par le Concepteur Windows Form.</span>
    InitializeComponent<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">' Création de la liste des transformation :</span>
    <span style="color: #008080; font-style: italic;">' - Le tag de chaque item contiendra l'identifiant en base de données.</span>
    <span style="color: #008080; font-style: italic;">' - On utilisera la méthode AddHandler pour gérer le clic sur un item</span>
    <span style="color: #008080; font-style: italic;">'   avec la fonction tsmiTransformation_Click.</span>
    InitLstTransformations<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Private</span> <span style="color: #0600FF;">Sub</span> tsmiTransformation_Click<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> sender <span style="color: #FF8000;">As</span> System.<span style="color: #FF0000;">Object</span>, <span style="color: #FF8000;">ByVal</span> e <span style="color: #FF8000;">As</span> System.<span style="color: #0000FF;">EventArgs</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">'Récupération de l'item cliquée.</span>
    <span style="color: #0600FF;">Dim</span> myItem <span style="color: #FF8000;">As</span> ToolStripMenuItem = TryCast<span style="color: #000000;">&#40;</span>sender, ToolStripMenuItem<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">If</span> myItem <span style="color: #FF8000;">Is</span> <span style="color: #FF8000;">Nothing</span> <span style="color: #FF8000;">Then</span> <span style="color: #0600FF;">Exit</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">' Récupération du code à exécuter qui est stocké en BDD.</span>
    <span style="color: #0600FF;">Dim</span> vbCode <span style="color: #FF8000;">As</span> <span style="color: #FF8000;">String</span> = <span style="color: #FF8000;">Me</span>.<span style="color: #0000FF;">getTransformationCode</span><span style="color: #000000;">&#40;</span>myItem.<span style="color: #0000FF;">Tag</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #FF8000;">Me</span>.<span style="color: #0000FF;">Image</span> = ExecuteTransformation<span style="color: #000000;">&#40;</span>vbCode, <span style="color: #FF8000;">Me</span>.<span style="color: #0000FF;">Image</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></pre></div></div>

<p>On sait que la fonction ExecuteTransformation aura le prototype suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Private</span> <span style="color: #0600FF;">Function</span> ExecuteTransformation<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> vbCode <span style="color: #FF8000;">As</span> <span style="color: #FF8000;">String</span>, <span style="color: #FF8000;">ByVal</span> img <span style="color: #FF8000;">As</span> Image<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Image</pre></div></div>

<p>Bien ! Maintenant que le prototypage est fait, il ne reste plus grand chose&#8230; Ah ben si, on n&#8217;a toujours pas vu comment évaluer/exécuter la chaine <code>vbCode</code> comme si c&#8217;était du code VB !</p>
<p>J&#8217;ai dit que ce n&#8217;était pas très compliqué, mais si je vous donnais le code sans explication, vous pourriez trouver ça complexe ! Ben oui, les classes utilisées pour cette opération ne sont pas si courantes que ça&#8230; Mais pas de panique, après une brève explication de la démarche, vous trouverez ça aussi simple que compter jusqu&#8217;à 10 en binaires !</p>
<p>Dans le Framework .Net, à l&#8217;intérieur de l&#8217;espace de noms <code>Microsoft.VisualBasic</code>, se trouve une classe nommée <code>VBCodeProvider</code>. Cette classe vous &#8220;fournit un accès aux instances du générateur de code et du compilateur de code Visual Basic&#8221; (dixit la <a href="http://msdn2.microsoft.com/fr-fr/library/microsoft.visualbasic.vbcodeprovider(VS.80).aspx">MSDN</a>), ce qui veut dire que grâce à cette classe, vous allez pouvoir générer des assembly et/ou des exécutable .Net à partir d&#8217;une chaine représentant du code source VB.Net. Dans notre exemple, la génération d&#8217;un assembly pour chaque commande du menu transformation changerait rapidement le répertoire de notre application en un gigantesque foutoir. Sauf que <code>VBCodeProvider</code> permet également de générer ces assembly directement en mémoire ! Et donc, avec un peu d&#8217;imagination, d&#8217;exécuter du code à la volée ! Pour cela, on va donc utiliser un objet <code>VBCodeProvider</code>, ainsi qu&#8217;un objet <code>CompilerParameters</code> (je vous laisse regarder la <a href="http://msdn2.microsoft.com/fr-fr/library/system.codedom.compiler.compilerparameters(VS.80).aspx">MSDN</a>) qui permet de configurer le compilateur VB. On va compiler une classe (appelons la <code>EvalVbCode</code>) qui contiendra une méthode (appelons la <code>EvalTransformation</code>) qui contiendra le code récupéré dans la base de données. Une fois l&#8217;assembly généré, il ne reste plus qu&#8217;à appeler la méthode (avec la Reflexion) et à récupérer l&#8217;image transformée&#8230; Simple, non ?!</p>
<p>Prêts ? Alors, prenez une bonne inspiration, et c&#8217;est parti :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Private</span> <span style="color: #0600FF;">Function</span> ExecuteTransformation<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> vbCode <span style="color: #FF8000;">As</span> <span style="color: #FF8000;">String</span>, <span style="color: #FF8000;">ByVal</span> img <span style="color: #FF8000;">As</span> Image<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Image
    <span style="color: #0600FF;">Dim</span> vbCodeProv <span style="color: #FF8000;">As</span> VBCodeProvider = <span style="color: #FF8000;">New</span> VBCodeProvider
    <span style="color: #0600FF;">Dim</span> cParam <span style="color: #FF8000;">As</span> CompilerParameters = <span style="color: #FF8000;">New</span> CompilerParameters
&nbsp;
    <span style="color: #008080; font-style: italic;">' Ajout des références</span>
    cParam.<span style="color: #0000FF;">ReferencedAssemblies</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;System.dll&quot;</span><span style="color: #000000;">&#41;</span>
    cParam.<span style="color: #0000FF;">ReferencedAssemblies</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;System.Drawing.dll&quot;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">' Options du compilateur</span>
    cParam.<span style="color: #0000FF;">CompilerOptions</span> = <span style="color: #808080;">&quot;/t:library&quot;</span>  <span style="color: #008080; font-style: italic;">'L'assembly est une bibliothèque de classe,</span>
    cParam.<span style="color: #0000FF;">GenerateInMemory</span> = <span style="color: #0600FF;">True</span>         <span style="color: #008080; font-style: italic;">'générée uniquement en mémoire.</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">' Génération du code source</span>
    <span style="color: #0600FF;">Dim</span> sCode <span style="color: #FF8000;">As</span> System.<span style="color: #0000FF;">Text</span>.<span style="color: #0000FF;">StringBuilder</span> = <span style="color: #FF8000;">New</span> System.<span style="color: #0000FF;">Text</span>.<span style="color: #0000FF;">StringBuilder</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;Imports System&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;Imports System.Drawing&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;Imports System.Diagnostics&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;Namespace VotreNamespace&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; <span style="color: #808080;">&quot;Class EvalVbCode&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;Public Function EvalTransformation(ByVal img As Image) as Image&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;Try&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbCode<span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;Catch ex As Exception&quot;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">' En cas d'erreur : console de debug ET renvoie Nothing</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;Debug.WriteLine(ex.Message)&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;Return Nothing&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;End Try&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; vbTab &amp; <span style="color: #808080;">&quot;End Function&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span>vbTab &amp; <span style="color: #808080;">&quot;End Class&quot;</span><span style="color: #000000;">&#41;</span>
    sCode.<span style="color: #0000FF;">AppendLine</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;End Namespace&quot;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">' Code de la classe dans la console de debug</span>
    <span style="color: #008000;">Debug</span>.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">&#40;</span>sCode.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">' Résultat de la compilation</span>
    <span style="color: #0600FF;">Dim</span> cResult <span style="color: #FF8000;">As</span> CompilerResults = vbCodeProv.<span style="color: #0000FF;">CompileAssemblyFromSource</span><span style="color: #000000;">&#40;</span>cParam, sCode.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">' Récupération de l'assembly généré</span>
    <span style="color: #0600FF;">Dim</span> myAssembly <span style="color: #FF8000;">As</span> System.<span style="color: #0000FF;">Reflection</span>.<span style="color: #FF8000;">Assembly</span> = cResult.<span style="color: #0000FF;">CompiledAssembly</span>
    <span style="color: #008080; font-style: italic;">' Instanciation de EvalVbCode</span>
    <span style="color: #0600FF;">Dim</span> oEvalVbCode <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Object</span> = myAssembly.<span style="color: #0000FF;">CreateInstance</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;VotreNamespace.EvalVbCode&quot;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">' Récupération du type de EvalVbCode</span>
    <span style="color: #0600FF;">Dim</span> tEvalVbCode <span style="color: #FF8000;">As</span> Type = oEvalVbCode.<span style="color: #804040;">GetType</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">' Récupération de la méthode EvalTransformation</span>
    <span style="color: #0600FF;">Dim</span> methodEvalTrans <span style="color: #FF8000;">As</span> MethodInfo = tEvalVbCode.<span style="color: #0000FF;">GetMethod</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;EvalTransformation&quot;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">' Invocation de la méthode EvalTransformation</span>
    <span style="color: #0600FF;">Dim</span> myImage <span style="color: #FF8000;">As</span> Image = methodEvalTrans.<span style="color: #0000FF;">Invoke</span><span style="color: #000000;">&#40;</span>oEvalVbCode, <span style="color: #FF8000;">New</span> <span style="color: #FF0000;">Object</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>img<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    Return myImage
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

<p>Et voilà ! Le code est exécuté à la volée ! N&#8217;oubliez pas d&#8217;indenter un minimum votre code, afin de pouvoir le lire dans la console de debug. Et maintenant, réfléchissez un peu plus aux applications d&#8217;une telle technique. Et n&#8217;oubliez pas que vous pouvez également générez les assembly et/ou applications sous forme de fichier sur le disque, puis utiliser la réflection pour les charger dynamiquement durant l&#8217;exécution de l&#8217;application.</p>
<p>Bon code !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/12/19/evaluationexecution-dune-chaine/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Wiki &#038; P/Invoke</title>
		<link>http://www.laumaille.net/2007/12/13/wiki-pinvoke/</link>
		<comments>http://www.laumaille.net/2007/12/13/wiki-pinvoke/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 13:40:52 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[.Net]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/12/13/wiki-pinvoke/</guid>
		<description><![CDATA[Un très court article pour présenter le site (un wiki en fait) http://www.pinvoke.net/ qui contient une mine d&#8217;informations pour utiliser les fonctions d&#8217;API windows en .Net. Ce wiki contient la liste détaillé de quasiment toutes les DLL windows, la liste des fonctions et enumérations incluses dans chaque DLL, un lien vers l&#8217;aide de la MSDN [...]]]></description>
			<content:encoded><![CDATA[<p>Un très court article pour présenter le site (un wiki en fait) <a href="http://www.pinvoke.net/">http://www.pinvoke.net/</a> qui contient une mine d&#8217;informations pour utiliser les fonctions d&#8217;API windows en .Net. Ce wiki contient la liste détaillé de quasiment toutes les DLL windows, la liste des fonctions et enumérations incluses dans chaque DLL, un lien vers l&#8217;aide de la MSDN dans chaque article, ainsi que le code de déclaration pour utiliser ces fonctions, des exemples, etc&#8230; Le tout en C# et/ou VB.Net !</p>
<p>Une mine d&#8217;or, je vous dis&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/12/13/wiki-pinvoke/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Motifs de Création : Monteur</title>
		<link>http://www.laumaille.net/2007/12/06/motifs-de-creation-monteur/</link>
		<comments>http://www.laumaille.net/2007/12/06/motifs-de-creation-monteur/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 11:25:28 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[Traduction]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/12/06/motifs-de-creation-monteur/</guid>
		<description><![CDATA[Troisième article dans la série des Design Patterns (ou Motifs de Conception), celui-ci nous expliquera le rôle et l’utilisation du motif Monteur (Builder)
But
Séparer la construction d&#8217;un objet complexe de sa représentation, afin qu&#8217;un même processus de constrauction puisse créer différentes représentations.
Autre Nom
Builder
Exemple
Un lecteur pour le format d&#8217;échange de documents RTF (Rich Texte Format) devrait être [...]]]></description>
			<content:encoded><![CDATA[<p>Troisième article dans la série des Design Patterns (ou Motifs de Conception), celui-ci nous expliquera le rôle et l’utilisation du motif Monteur (Builder)</p>
<h3>But</h3>
<p>Séparer la construction d&#8217;un objet complexe de sa représentation, afin qu&#8217;un même processus de constrauction puisse créer différentes représentations.</p>
<h3>Autre Nom</h3>
<p>Builder</p>
<h3>Exemple</h3>
<p>Un lecteur pour le format d&#8217;échange de documents RTF (Rich Texte Format) devrait être capable de convertir le RTF vers de multiples formats textes. Le lecteur pourrait convertir des documents RTF en texte ASCII ou en un widget texte pouvant être édité interactivement. Le problème, cependant, est que le nombre de conversions possible est sans fin. Donc, on devrait pouvoir ajouter de nouvelles conversions sans modifier le lecteur.</p>
<p><span id="more-28"></span></p>
<p>Une solution serait de configurer la classe LecteurRTF avec un objet ConvertisseurDeTexte qui convertirait le RTF en une autre représentation textuelle. Pendant que le LecteurRTF analyse le document RTF, il utilise le ConvertisseurDeTexte pour effectuer la conversion. Chaque fois que le LecteurRTF reconnaît un motif RTF (que ce soit du texte simple ou un symbole de contrôle RTF), il fait une demande au ConvertisseurDeTexte pour convertir le motif. Les objets ConvertisseurDeTexte sont responsables tant de la conversion de données que de la représentation d&#8217;un motif dans un format particulier.</p>
<p>Les sous-classes de ConvertisseurDeTexte sont spécialisées dans différentes conversions vers différents formats. Par exemple, un ConvertisseurASCII ignore les demandes de conversion qui ne concernent pas du texte simple. D&#8217;un autre côté, un ConvertisseurTeX va implémenter des opérations pour toutes les requêtes afin de produire une représentation TeX qui va reproduire toutes les informations de style du texte. Un ConvertisseurWidgetTexte va produire un objet d&#8217;interface utilisateur complexe qui permettra à l&#8217;utilisateur de voir et d&#8217;éditer le texte.</p>
<p style="text-align: center"><a href="http://www.laumaille.net/wp-content/uploads/2007/12/monteur_1.gif" title="Schéma d’exemple - Monteur" rel="thumbnail"><img src="http://www.laumaille.net/wp-content/uploads/2007/12/monteur_1.thumbnail.gif" alt="Schéma d’exemple - Monteur" /></a></p>
<p>Chaque type de classe de convertisseur va implémenter le mécanisme de création et d&#8217;assemblage d&#8217;un objet complexe en n&#8217;exposant qu&#8217;une interface abstraite. Le convertisseur est séparé du lecteur, qui est responsable de l&#8217;analyse du document RTF.</p>
<p>Le motif de conception Monteur prend en compte toutes ces relations. Chaque classe de convertisseur est appelée &#8220;monteur&#8221; dans le motif, et le lecteur est appelé le &#8220;directeur&#8221;. Appliqué à cet exemple, le Monteur sépare les algorithmes pour l&#8217;interprétation d&#8217;un format texte (c&#8217;est-à-dire l&#8217;analyseur de documents RTF) de la manière dont un format de conversion est créé et représenté. Cela nous permet de réutiliser l&#8217;algorithme d&#8217;analyse du LecteurRTF afin de créer différentes représentation de documents RTF : il suffit de configurer le LecteurRTF avec différentes sous-classes de ConvertisseurDeTexte.</p>
<h3>Applicabilité</h3>
<p>Utilisez le motif de conception Monteur quand :</p>
<ul>
<li>L&#8217;algorithme de création d&#8217;un objet complexe doit être indépendant des parties qui construisent l&#8217;objet et de comment celles-ci sont assemblées.</li>
<li>Le processus de construction doit permettre différentes représentations de l&#8217;objet construit.</li>
</ul>
<h3>Structure</h3>
<p style="text-align: center"><a href="http://www.laumaille.net/wp-content/uploads/2007/12/monteur_2.gif" title="Schéma de structure - Monteur" rel="thumbnail"><img src="http://www.laumaille.net/wp-content/uploads/2007/12/monteur_2.thumbnail.gif" alt="Schéma de structure - Monteur" /></a></p>
<h3>Participants</h3>
<ul>
<li>Monteur (ConvertisseurDeTexte)
<ul>
<li>Spécifie une interface abstraite afin de créer les parties d&#8217;un objet Produit.</li>
</ul>
</li>
<li>MonteurConcret (ConvertisseurASCII, ConvertisseurTeX, ConvertisseurWidgetTexte)
<ul>
<li>Construit et assmble les pièces du produit en implémentant l&#8217;interface Monteur.</li>
<li>Définit et garde une trace de la représentation qu&#8217;il crée.</li>
<li>Fournit une interface pour retrouver le produit (i.e., GetTexteASCII, GetTexteWidget)</li>
</ul>
</li>
<li>Directeur (LecteurRTF)
<ul>
<li>Construit un objet en utilisant l&#8217;interface Monteur.</li>
</ul>
</li>
<li>Produit (TexteASCII, TexteTeX, TexteWidget)
<ul>
<li>Représente l&#8217;objet complexe en construction. MonteurConcret construit la représentation interne du produit et définit le processus par lequel il est assemblé.</li>
<li>Comprend les classes qui définissent les éléments constitutifs, y compris les interfaces pour l&#8217;assemblage des pièces en un résultat final.</li>
</ul>
</li>
</ul>
<h3>Collaboration</h3>
<ul>
<li>Le client crée l&#8217;objet Directeur et le configure avec l&#8217;objet Monteur désiré.</li>
<li>Le Directeur notifie le Monteur à chaque fois qu&#8217;une partie du Produit doit être construite.</li>
<li>Le Monteur gère les demandes du Directeur et ajoute des parties au Produit.</li>
<li>Le client récupère le Produit auprès du Monteur.</li>
</ul>
<p>Le diagramme d&#8217;interaction suivant illustre la manière dont le Monteur et le Directeur coopèrent avec le client.</p>
<p style="text-align: center"><a href="http://www.laumaille.net/wp-content/uploads/2007/12/monteur_3.gif" title="Diagramme de collaboration - Monteur" rel="thumbnail"><img src="http://www.laumaille.net/wp-content/uploads/2007/12/monteur_3.thumbnail.gif" alt="Diagramme de collaboration - Monteur" /></a></p>
<h3>Conséquences</h3>
<p>Voici les principales conséquences du motif de conception Monteur :</p>
<ol>
<li><strong>Il permet de varier la représentation interne d&#8217;un produit.</strong> L&#8217;objet Monteur fournit une interface abstraite au Directeur pour la construction du produit. L&#8217;interface permet au monteur de cacher la représentation et la structure interne du produit. Elle cache également la manière dont est assemblé le produit. Comme le produit est construit au travers d&#8217;une interface abstraite, tout ce que vous avez à faire pour changer la représentation interne du produit est de définir un nouveau type de monteur.</li>
<li><strong>Il isole le code de construction et le code de représentation.</strong> Le motif de conception Monteur améliore la modularité en encapsulant la manière dont un objet complexe est construit et représenté. Les clients n&#8217;ont pas besoin de savoir quoi que ce soit à propos de la classe qui définit la structure interne du produit ; ces classes n&#8217;apparaissent pas dans l&#8217;interface Monteur.Chaque MonteurConcret contient tout le code pour créer et assembler un certain type de produit. Le code n&#8217;est écrit qu&#8217;une fois ; puis différents Directeurs peuvent le réutiliser afin de construire des Produits dérivants d&#8217;un même ensemble de pièces. Dans l&#8217;exemple du RTF que l&#8217;on vient de voir, nous pourrions définir un lecteur pour un format autre que RTF, comme un LecteurSGML, et utiliser les même ConvertisseursDeTexte pour générer du TexteASCII, du TexteTeX ou du TexteWidget venant de documents SGML.</li>
<li><strong>Il permet un meilleur contrôle du processus de construction.</strong> À la différence des motifs de création qui construisent un produit d&#8217;un seul coup, le motif de conception Monteur construit le produit étape par étape sous le contrôle du Directeur. Ce n&#8217;est que lorsque le produit est fini que le Directeur récupère le produit auprès du Monteur. On peut donc dire que l&#8217;interface Monteur reflète mieux le processus de construction d&#8217;un produit que les autres motifs de création. Cela permet un meilleur contrôle du processus de construction et, par conséquent, sur la structure interne du produit résultant.</li>
</ol>
<h3>Implémentation</h3>
<p>Typiquement, il y a une classe abstraite Monteur qui définit une opération pour chaque composant que le Directeur pourrait lui demander de créer. Par défaut, ces opérations ne font rien. Une classe MonteurConcret surcharge les opérations concernant les composants dont la création l&#8217;intéresse.</p>
<p>Quelques autres questions à se poser sur l&#8217;implémentation :</p>
<ol>
<li><strong>Assemblage et construction d&#8217;interface.</strong> Les Monteurs construisent leurs produit dans un mode étape par étape. Par conséquent, l&#8217;interface de la classe Monteur doit être assez générale pour permettre la construction de produits pour tout type de MonteurConcret.L&#8217;une des principales questions de conception concerne le modèle pour le processus de construction et d&#8217;assemblage. Un modèle dans lequel les résultats des demandes de construction sont simpllement ajoutés les uns aux autres est habituellement suffisant. Dans l&#8217;exemple du RTF, le Monteur convertit et ajoute le motif suivant au texte qu&#8217;il a convertit jusqu&#8217;ici.Mais parfois, vous pourriez avoir besoin d&#8217;accéder à des parties du produit construit plus tôt. Dans l&#8217;exemple du Labyrinthe présenté au chapitre &#8220;Exemple de code&#8221;, l&#8217;interface MonteurDeLabyrinthe permet d&#8217;ajouter une porte entre des Pièces existantes. Les structures arborescentes comme les arbres d&#8217;analyse vus plus bas sont un autre exemple. Dans ce cas, le Monteur va renvoyer des noeuds enfants au Directeur, qui va ensuite les retourner au Monteur pour construire les noeuds parents.</li>
<li><strong>Pourquoi ne pas rendre abstraites les classes de produits également ?</strong> Dans la plupart des cas, les produits construits par les MonteurConcret diffèrent tellement dans leur représentation qu&#8217;il y a très peu de gain à donner aux différents produits une classe parente commune. Dans l&#8217;exemple du RTF, les objets TexteASCII et TexteWidget sont trop différents pour avoir une interface commune, et n&#8217;en ont pas besoin. Comme le client va configurer le Directeur avec le bon MonteurConcret, le client est en position de savoir quelle sous-classe de Monteur est utilisée et peut gérer ses produits dans ce sens.</li>
<li><strong>Par défaut, les méthodes du Monteur sont vides.</strong> En C++, les méthodes de construction ne sont intentionnellement pas déclarées comme de pures fonctions membres virtuelles. Au lieu de cela, elles sont définies comme des méthodes vide, laissant le client surcharger uniquement celles qui l&#8217;intéressent.</li>
</ol>
<h3>Exemple de code</h3>
<p>On va définir une variante de la fonction NouveauLabyrinthe qui va prendre un monteur de type MonteurDeLabyrinthe en argument.</p>
<p>La classe MonteurDeLabyrinthe définit l&#8217;interface suivante pour construire des labyrinthes :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> MonteurDeLabyrinthe
&nbsp;
    Protected <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MonteLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePièce<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> dePièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByVal</span> àPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> GetLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
        Return <span style="color: #FF8000;">Nothing</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Cette interface peut créer trois choses : (1) le labyrinthe, (2) des pièces avec un numéro de pièce particulier, et (3) des portes entre des pièces numérotées. La fonction GetLabyrinthe retourne un labyrinthe au client. Les sous-classes de MonteurDeLabyrinthe vont surcharger ces opérations pour renvoyer le labyrinthe qu&#8217;elles auront construit.</p>
<p>Toutes les opérations de construction de labyrinthe de MonteurDeLabyrinthe ne font rien par défaut. Elles ne sont pas déclarées comme purement virtuelles afin de laisser aux classes dérivées le soin de surcharger uniquement les méthodes qui les intéressent.</p>
<p>Etant donné l&#8217;interface de MonteurDeLabyrinthe, on peut modifier la fonction NouveauLabyrinthe afin qu&#8217;elle prenne ce Monteur en paramètre.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> NouveauLabyrinthe<span style="color: #000000;">&#40;</span>monteur <span style="color: #FF8000;">as</span> MonteurDeLabyrinthe<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
&nbsp;
    monteur.<span style="color: #0000FF;">MonteLabyrinthe</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    monteur.<span style="color: #0000FF;">MontePi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span>
    monteur.<span style="color: #0000FF;">MontePi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span>
    monteur.<span style="color: #0000FF;">MontePorte</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1</span>, <span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span>
&nbsp;
    Return monteur.<span style="color: #0000FF;">GetLabyrinthe</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

<p>Comparez cette version de NouveauLabyrinthe à l&#8217;originale. Notez bien comment le Monteur cache la représentation interne du labyrinthe (c&#8217;est-à-dire, les classes qui définissent les pièces, les portes et les murs), et comment ces parties sont assemblées pour produire le labyrinthe final. On peut deviner qu&#8217;il existe des classes pour les pièces et les portes, mais aucun indice ne laisse à penser qu&#8217;il en existe pour les murs. Cela permet de changer plus facilement la manière dont un labyrinthe est représentée, puisque aucun des clients de MonteurDeLabyrinthe n&#8217;a besoin d&#8217;être modifié.</p>
<p>Comme les autres motifs de création, le motif de conception Monteur encapsule la manière dont les objets sont créés, dans ce cas : au travers de l&#8217;interface définie par MonteurDeLabyrinthe. Cela signifie que l&#8217;on peut réutiliser MonteurDeLabyrinthe afin de construire différents types de labyrinthes. La fonction NouveauLabyrintheComplexe en donne un exemple :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> NouveauLabyrintheComplexe<span style="color: #000000;">&#40;</span>monteur <span style="color: #FF8000;">as</span> MonteurDeLabyrinthe<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
&nbsp;
    monteur.<span style="color: #0000FF;">MonteLabyrinthe</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    monteur.<span style="color: #0000FF;">MontePi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span>
    monteur.<span style="color: #0000FF;">MontePi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span>
    <span style="color: #008080; font-style: italic;">'...</span>
    monteur.<span style="color: #0000FF;">MontePi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1001</span><span style="color: #000000;">&#41;</span>
&nbsp;
    Return monteur.<span style="color: #0000FF;">GetLabyrinthe</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

<p>Notez bien que MonteurDeLabyrinthe ne crée pas le labyrinthe lui-même ; son but principal est simplement de définir une interface pour la création de labyrinthes. Il définit une implémentation vide principalement par commodité. Les classes dérivées de MonteurDeLabyrinthe font le véritable travail.</p>
<p>La sous-classe MonteurDeLabyrintheStandard est une implémentation qui construit de simples labyrinthes. Elle garde une trace du labyrinthe qu&#8217;elle construit dans la variable _labyrintheCourant.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> MonteurDeLabyrintheStandard
    <span style="color: #0600FF;">Inherits</span> MonteurDeLabyrinthe
&nbsp;
    <span style="color: #FF8000;">Private</span> _labyrintheCourant <span style="color: #FF8000;">as</span> Labyrinthe
&nbsp;
    <span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MonteLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePièce<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> dePièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByVal</span> àPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> GetLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Private</span> <span style="color: #0600FF;">Function</span> MurCommun<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> p1 <span style="color: #FF8000;">as</span> Pièce, <span style="color: #FF8000;">ByVal</span> p2 <span style="color: #FF8000;">as</span> Pièce<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Direction
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>MurCommun est une fonction utilitaire déterminant la direction d&#8217;un mur commun entre deux pièces.</p>
<p>Le constructeur de MonteurDeLabyrintheStandard initialise simplement _labyrintheCourant.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #FF8000;">Me</span>._labyrintheCourant = <span style="color: #FF8000;">Nothing</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></pre></div></div>

<p>MonteLabyrinthe instancie un Labyrinthe que les autres opérations vont assembler et éventuellement retourne au client (avec GetLabyrinthe).</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> MonteLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #FF8000;">Me</span>._labyrintheCourant = <span style="color: #FF8000;">New</span> Labyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> GetLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
    Return <span style="color: #FF8000;">Me</span>._labyrintheCourant
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

<p>La procédure MontePièce crée une pièce et construit les murs autour d&#8217;elle :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePièce<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #0600FF;">If</span> <span style="color: #000000;">&#40;</span><span style="color: #FF8000;">Me</span>._labyrintheCourant.<span style="color: #0000FF;">PieceNo</span><span style="color: #000000;">&#40;</span>numPièce<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Is</span> <span style="color: #FF8000;">Nothing</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Then</span>
        <span style="color: #0600FF;">Dim</span> maPièce <span style="color: #FF8000;">as</span> Pièce = <span style="color: #FF8000;">New</span> Pièce<span style="color: #000000;">&#40;</span>numPièce<span style="color: #000000;">&#41;</span>
        <span style="color: #FF8000;">Me</span>._labyrintheCourant.<span style="color: #0000FF;">AjouterPiece</span><span style="color: #000000;">&#40;</span>maPièce<span style="color: #000000;">&#41;</span>
        maPièce.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Nord<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        maPièce.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Sud<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        maPièce.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Est<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        maPièce.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Ouest<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></pre></div></div>

<p>Pour construire une porte entre deux pièces, MonteurDeLabyrintheStandard prend les deux pièces dans le labyrinthe et trouve leur mur commun :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> dePièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByVal</span> àPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #0600FF;">Dim</span> p1 <span style="color: #FF8000;">as</span> Pièce = <span style="color: #FF8000;">Me</span>._labyrintheCourant.<span style="color: #0000FF;">PieceNo</span><span style="color: #000000;">&#40;</span>dePièce<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">Dim</span> p2 <span style="color: #FF8000;">as</span> Pièce = <span style="color: #FF8000;">Me</span>._labyrintheCourant.<span style="color: #0000FF;">PieceNo</span><span style="color: #000000;">&#40;</span>àPièce<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">Dim</span> po <span style="color: #FF8000;">as</span> Porte = <span style="color: #FF8000;">New</span> Porte<span style="color: #000000;">&#40;</span>p1, p2<span style="color: #000000;">&#41;</span>
&nbsp;
    p1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>MurCommun<span style="color: #000000;">&#40;</span>p1, p2<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> = po
    p2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>MurCommun<span style="color: #000000;">&#40;</span>p2, p1<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> = po
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

<p>Les clients peuvent maintenant utiliser NouveauLabyrinthe en conjonction avec MonteurDeLabyrintheStandard pour créer un labyrinthe :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Dim</span> laby <span style="color: #FF8000;">as</span> Labyrinthe
<span style="color: #0600FF;">Dim</span> jeu <span style="color: #FF8000;">as</span> JeuDuLabyrinthe
<span style="color: #0600FF;">Dim</span> monteur <span style="color: #FF8000;">as</span> MonteurDeLabyrintheStandard
&nbsp;
jeu.<span style="color: #0000FF;">NouveauLabyrinthe</span><span style="color: #000000;">&#40;</span>monteur<span style="color: #000000;">&#41;</span>
laby = monteur.<span style="color: #0000FF;">GetLabyrinthe</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<p>On pourrait avoir mis toutes les opérations de MonteurDeLabyrintheStandard dans Labyrinthe et laissé chaque Labyrinthe se monter lui-même. Mais faire une plus petite classe Labyrinthe la rend plus simple à comprendre et à modifier, et MonteurDeLabyrintheStandard est facile à séparer de Labyrinthe. Plus important, séparer les deux permet d&#8217;avoir  une multitude de MonteurDeLabyrinthe, chacun utilisant des classes différentes pour les pièces, les murs et les portes.</p>
<p>Un MonteurDeLabyrinthe plus exotique serait MonteurDeLabyrintheComptable. Ce monteur ne crée pas du tout de Labyrinthe ; il ne fait que compter les différents types de composants qui auraient été créés.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> MonteurDeLabyrintheComptable
    <span style="color: #0600FF;">Inherits</span> MonteurDeLabyrinthe
&nbsp;
    <span style="color: #FF8000;">Private</span> _portes <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>
    <span style="color: #FF8000;">Private</span> _pieces <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MonteLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePièce<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> dePièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByVal</span> àPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> AjouterMur<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByVal</span> <span style="color: #0600FF;">dir</span> <span style="color: #FF8000;">as</span> Direction<span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> GetCompte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByRef</span> nbPortes <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByRef</span> nbPièces <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
        <span style="color: #008080; font-style: italic;">'...</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Le constructeur initialise les compteurs, et les opérations surchargées de MonteurDeLabyrinthe s&#8217;occupent de les incrémenter comme il faut.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #FF8000;">Me</span>._portes = <span style="color: #FF0000;">0</span>
    <span style="color: #FF8000;">Me</span>._pieces = <span style="color: #FF0000;">0</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePièce<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
    <span style="color: #FF8000;">Me</span>._pieces = <span style="color: #FF8000;">Me</span>._pieces + <span style="color: #FF0000;">1</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Sub</span> MontePorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> dePièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByVal</span> àPièce <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
    <span style="color: #FF8000;">Me</span>._portes = <span style="color: #FF8000;">Me</span>._portes + <span style="color: #FF0000;">1</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> GetCompte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByRef</span> nbPortes <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>, <span style="color: #FF8000;">ByRef</span> nbPièces <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
    nbPortes = <span style="color: #FF8000;">Me</span>._portes
    nbPièces = <span style="color: #FF8000;">Me</span>._pieces
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></pre></div></div>

<p>Et voici comment un client pourrait utiliser un MonteurDeLabyrintheComptable :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Dim</span> pieces <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>
<span style="color: #0600FF;">Dim</span> portes <span style="color: #FF8000;">as</span> <span style="color: #FF0000;">Integer</span>
<span style="color: #0600FF;">Dim</span> jeu <span style="color: #FF8000;">as</span> JeuDuLabyrinthe
<span style="color: #0600FF;">Dim</span> monteur <span style="color: #FF8000;">as</span> MonteurDeLabyrintheComptable
&nbsp;
jeu.<span style="color: #0000FF;">NouveauLabyrinthe</span><span style="color: #000000;">&#40;</span>monteur<span style="color: #000000;">&#41;</span>
monteur.<span style="color: #0000FF;">GetCompte</span><span style="color: #000000;">&#40;</span>portes, pieces<span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #0600FF;">MsgBox</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;Le labyrinthe contient &quot;</span> &amp;amp; pieces &amp;amp; <span style="color: #808080;">&quot; pièces et &quot;</span> &amp;amp; portes &amp;amp; <span style="color: #808080;">&quot; portes.&quot;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<h3>Utilisations connues</h3>
<p>L&#8217;application de conversion RTF vient de <a href="http://www.ivtools.org/ivtools/etplusplus.html">ET++</a>. Son bloc de construction de texte utilise un Monteur pour traiter le texte stocké au format RTF.</p>
<p>Monteur est un motif de conception commun en <a href="ftp://alpha.gnu.org/gnu/smalltalk/gst.html">GNU Smalltalk</a> :</p>
<ul>
<li>La classe Parser du système interne de compilation est un Directeur qui prend un objet ProgramNodeBuilder en argument. Un objet Parser notifie son objet ProgramNodeBuilder à chaque fois qu&#8217;il reconnaît une construction syntaxique. Quand l&#8217;analyse est terminée, Parser demande au monteur l&#8217;arbre d&#8217;analyse qu&#8217;il a construit et le retourne au client.</li>
<li>ClassBuilder est un Monteur que les classes utilisent pour créer des sous-classes d&#8217;elles-même. Dans ce cas, une classe est à la fois le Directeur et le Produit.</li>
<li>ByteCodeStream est un Monteur qui crée une méthode compilée en tant que tableau d&#8217;octets. ByteCodeStream est une utilisation non-standard du mitif de conception Monteur, parce que l&#8217;objet complexe qu&#8217;il construit est encodé comme un tableau d&#8217;octets, et non comme un objet SmallTalk standard. Mais l&#8217;interface de ByteCodeStream est typique du Monteur, et il serait très simple de remplacer ByteCodeStream par une classe différente représentant un programme comme un objet composé.</li>
</ul>
<p>Le framework &#8220;Service Configurator&#8221; d&#8217;<a href="http://www.cs.wustl.edu/~schmidt/ACE.html">Adaptive Communications Environment</a> utilise un Monteur afin de construire les composants de service réseau liés à un serveur en cours d&#8217;exécution. Les composants sont décrits avec un langage de configuration qui est analysé par un <a href="http://fr.wikipedia.org/wiki/Analyse_LALR">parser LALR</a>. Les actions sémantiques de l&#8217;analyseur effectuent des opérations sur le Monteur qui ajoutent des informations au composant de service. Dans ce cas, l&#8217;analyseur est le Directeur.</p>
<h3>Voir Aussi</h3>
<p>La <a href="http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/">Fabrique Abstraite</a> est similaire au Monteur en ce sens qu&#8217;elle construit elle aussi des objets complexes. La différence principale est que le motif de création Monteur se focalise sur la construction d&#8217;objets complexes, étape par étape. Fabrique Abstraite met l&#8217;accent sur les familles d&#8217;objets produits (qu&#8217;ils soient simples ou complexes). Pour le motif de conception Monteur, le retour du produit est la phase finale, tandis que Fabrique Abstraite le retourne immédiatement.</p>
<p>Un <a href="#">Objet Composite</a> est ce que construit un Monteur la plupart du temps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/12/06/motifs-de-creation-monteur/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Motifs de Création : Fabrique Abstraite</title>
		<link>http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/</link>
		<comments>http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/#comments</comments>
		<pubDate>Tue, 04 Dec 2007 08:49:37 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[Traduction]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/</guid>
		<description><![CDATA[Deuxième article dans la série des Design Patterns (ou Motifs de Conception), celui-ci nous expliquera le rôle et l&#8217;utilisation du motif Fabrique Abstraite (Abstract Factory)
But
Fournir une interface pour la création de famille d&#8217;objets connexes ou dépendants sans indiquer leur classe concrète.
Autre Nom
Abstract Factory, Kit.
Exemple
Prenons un gestionnaire de composants d&#8217;interface utilisateur supportant un certain nombre de [...]]]></description>
			<content:encoded><![CDATA[<p>Deuxième article dans la série des Design Patterns (ou Motifs de Conception), celui-ci nous expliquera le rôle et l&#8217;utilisation du motif Fabrique Abstraite (Abstract Factory)</p>
<h3>But</h3>
<p>Fournir une interface pour la création de famille d&#8217;objets connexes ou dépendants sans indiquer leur classe concrète.</p>
<h3>Autre Nom</h3>
<p>Abstract Factory, Kit.</p>
<h3>Exemple</h3>
<p>Prenons un gestionnaire de composants d&#8217;interface utilisateur supportant un certain nombre de styles d&#8217;affichage, par exemple un style bleu et un style gris (comme les styles XP). Différents styles définissent différentes apparences et comportements pour les composants d&#8217;interface utilisateur tels que les barres de défilement, les fenêtres, et les boutons. Pour être portable sur les différents styles, une application ne devrait pas coder en dur ses composants pour un style particulier. L&#8217;instanciation de classes de composants spécifiques à un style au travers de l&#8217;application rendrait difficile la modification du style par la suite.<br />
<span id="more-25"></span><br />
On peut résoudre ce problème en définissant une classe abstraite FabriqueDeComposants déclarant une interface pour créer chaque type basique de composant. On crée aussi une classe abstraite pour chaque type de composant, et les sous-classes concrètes qui vont implémenter chaque composant pour un style spécifique. L&#8217;interface de FabriqueDeComposants a une méthode qui renvoie un nouvel objet Composant pour chaque classe abstraite de composant. Les applications clientes font appel à ces méthodes pour obtenir des instances de composants, mais elles n&#8217;ont pas conscience de la classe concrète qu&#8217;elles utilisent. Par conséquent les applications clientes restent indépendantes du style sélectionné.</p>
<p style="text-align: center"><a href="http://www.laumaille.net/wp-content/uploads/2007/12/fabriqueabstraite_1.gif" title="Schéma d’exemple - Fabrique Abstraite" rel="thumbnail"><img src="http://www.laumaille.net/wp-content/uploads/2007/12/fabriqueabstraite_1.thumbnail.gif" alt="Schéma d’exemple - Fabrique Abstraite" /></a></p>
<p>Il y a une sous-classe concrète de FabriqueDeComposants pour chaque style. Chaque sous-classe implémente les opérations pour créer les composants appropriés au style. Par exemple, la méthode CreerScrollBar de FabriqueDeComposantsBleus instancie et retourne une barre de défilement bleue, tandis que la même méthode dans la classe FabriqueDeComposantsGris renvoie une barre de défilement grise. Les applications clientes créent des composants uniquement via l&#8217;interface FabriqueDeComposants et n&#8217;ont pas connaissance des classes implémentant les composants pour un style donné. En d&#8217;autres termes, les applications clientes doivent seulement appliquer une interface définie par une classe abstraite, et non par une classe concrète particulière.</p>
<p>Une FabriqueDeComposants renforce également la cohésion entre les classes concrètes de composants. Une barre de défilement bleue doit être utilisée avec un bouton bleu dans une fenêtre bleue, et cette contrainte est automatiquement appliquée par l&#8217;utilisation de FabriqueDeComposantsBleus.</p>
<h3>Applicabilité</h3>
<p>Utilisez le motif Fabrique Abstraite quand :</p>
<ul>
<li>Un système doit être indépendant de la façon dont ses produits sont créés, composés et représentés.</li>
<li>Un système doit être configurée avec l&#8217;une des multiples familles de produits.</li>
<li>Des objets relatifs les uns aux autres sont fait pour être utilisés ensemble, et vous voulez renforcer cette contrainte.</li>
<li>Vous voulez fournir une bibliothèque de classes de produits, et vous voulez juste donner leur interface, et non leurs implémentations.</li>
</ul>
<h3>Structure</h3>
<p style="text-align: center"><a href="http://www.laumaille.net/wp-content/uploads/2007/12/fabriqueabstraite_2.gif" title="Schéma de Structure - Fabrique Abstraite" rel="thumbnail"><img src="http://www.laumaille.net/wp-content/uploads/2007/12/fabriqueabstraite_2.thumbnail.gif" alt="Schéma de Structure - Fabrique Abstraite" /></a></p>
<h3>Participants</h3>
<ul>
<li>FabriqueAbstraite <em>(FabriqueDeComposants)</em> :
<ul>
<li>Déclare une interface de création de <strong>ProduitAbstrait</strong>.</li>
</ul>
</li>
<li>FabriqueConcrete <em>(FabriqueDeComposantsBleus, FabriqueDeComposantsGris)</em> :
<ul>
<li>Implémente les méthodes de création de <strong>ProduitConcret</strong>.</li>
</ul>
</li>
<li>ProduitAbstrait <em>(ScrollBar, Fenetre, Bouton)</em> :
<ul>
<li>Déclare une interface pour un type de produit.</li>
</ul>
</li>
<li>ProduitConcret <em>(ScrollBarBleus, FenetreGris)</em> :
<ul>
<li>Définit un produit devant être créé par la <strong>FabriqueConcrete</strong> correspondante.</li>
<li>Implémente l&#8217;interface <strong>ProduitAbstrait</strong>.</li>
</ul>
</li>
<li>Client :
<ul>
<li>Utilise uniquement les interfaces déclarées par les classes <strong>FabriqueAbstraite</strong> et <strong>ProduitAbstrait</strong>.</li>
</ul>
</li>
</ul>
<h3>Collaboration</h3>
<ul>
<li>Normalement, une seule instance d&#8217;une classe FabriqueConcrete est crée au moment de l&#8217;exécution. Cette FabriqueConcrete va créer des objets ayant une implémentation particulière. Pour créer des objets d&#8217;une implémentation différente, l&#8217;application Client doit utiliser une autre FabriqueConcrete.</li>
<li>FabriqueAbstraite défère la création d&#8217;objet à ses sous-classes FabriqueConcrete.</li>
</ul>
<h3>Conséquences</h3>
<p>Le motif Fabrique Abstraite génère les avantages et les inconvénients suivants :</p>
<ol>
<li><strong>Il isole les classes concrètes.</strong> Le motif Fabrique Abstraite vous aide à contrôler les classes d&#8217;objets qu&#8217;une application peut créer. Comme une fabrique encapsule la responsabilité et le processus de création des objets, il isole le client des classes d&#8217;implémentation. Le client va manipuler les instances au travers de leurs interfaces abstraites. Les noms des classes de produits concrets sont isolés dans l&#8217;implémentation des fabriques concrètes ; ils n&#8217;apparaissent pas dans le code client.</li>
<li><strong>Il permet d&#8217;échanger facilement des familles de produit.</strong> La classe d&#8217;une fabrique concrète apparaît une seule fois dans l&#8217;application : là où elle est instanciée. Cela rend très simple le changement de fabrique utilisé par l&#8217;application. Le client peut utiliser différentes configurations de produits en modifiant simplement la fabrique concrète. COmme une fabrique abstraite crée une famille complète de produits, la famille entière de produit change en une seule opération. Dans notre example d&#8217;interface utilisateur, on peut passer des composants bleus aux composants gris en changeant simplement de fabrique de composant.</li>
<li><strong>Il garantit la cohérence entre les produits.</strong> Quand les objets d&#8217;une famille sont fait pour travailler ensemble, il est important qu&#8217;une application n&#8217;utilise que les objets d&#8217;une seule famille à la fois. Fabrique Abstraite met facilement cela en oeuvre.</li>
<li><strong>Il est difficile de prendre en charge de nouveaux types de produits.</strong> Etendre Fabrique Abstraite pour qu&#8217;elle supporte de nouveaux produits n&#8217;est pas facile. C&#8217;est parce que l&#8217;interface FabriqueAbstraite fixe l&#8217;ensemble de produits pouvant être créés. La prise en charge de nouveaux produits demande l&#8217;extension de l&#8217;interface de fabrication, ce qui implique de modifier la classe FabriqueAbstraite et toutes ses sous-classes. Nous discuterons d&#8217;une solution à ce problème dans la section suivante.</li>
</ol>
<h3>Implémentation</h3>
<p>Quelques techniques utiles pour implémenter le motif Fabrique Abstraite :</p>
<ol>
<li>Développer les fabriques en tant que <strong>Singleton</strong>. Une application à besoin, typiquement, d&#8217;une seule instance d&#8217;une FabriqueConcrete par famille de produit. Il est donc généralement préférable de les implémenter en tant que <a href="#">Singleton</a>.</li>
<li>Créer les produits. FabriqueAbstraite déclare seulement une interface pour créer les produits. C&#8217;est aux sous-classes ProduitsConcrets de les créer. La méthode la plus utilisée de faire ceci est de définir une méthode de fabrication (voir <a href="#">Fabrique</a>) pour chaque produit. Une fabrique concrète va spécifier l&#8217;implémentation de ses produits en surchargeant la méthode de fabrication pour chacun. Mais si cette implémentation est simple, elle demande une nouvelle classe de fabrique concrète pour chaque famille de produit, même si ces familles diffèrent très peu.</li>
<p>Si l&#8217;on risque d&#8217;avoir beaucoup de familles de produits, la fabrique concrète peut être implémentée en utilisant le motif <a href="#">Prototype</a>. La fabrique concrète est initialisée avec une instance prototypique de chaque produit de la famille, et crée un nouveau produit en copiant ce prototype. Cette approche basée sur Prototype élimine le besoin d&#8217;une nouvelle classe de fabrique concrète pour chaque famille de produit.</p>
<p>Voici une manière d&#8217;implémenter une fabrique basée sur Prototype en SmallTalk. La fabrique concrète stocke les prototypes à cloner dans un dictionnaire appelé partCatalog. La méthode <code>make:</code> retrouve le prototype et le clone :</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">make: <span style="color: #00007f;">partName</span>
       ^ <span style="">&#40;</span><span style="color: #00007f;">partCatalog</span> at: <span style="color: #00007f;">partName</span><span style="">&#41;</span> copy</pre></div></div>

<p>La fabrique concrète a une méthode pour ajouter une pièce au catalogue :</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">addPart: <span style="color: #00007f;">partTemplate</span> named: <span style="color: #00007f;">partName</span>   partCatalog at: <span style="color: #00007f;">partName</span> put: <span style="color: #00007f;">partTemplate</span></pre></div></div>

<p>Les Prototypes sont ajoutés à la fabrique avec un identifiant :</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">aFactory addPart: <span style="color: #00007f;">aPrototype</span> named: <span style="color: #7f0000;">#ACMEWidget</span></pre></div></div>

<li>Une variation de l&#8217;approche basée sur Prototype est possible dans les langages traitant les classes comme des objets de premier niveau (les langages orientés objets comme .Net, Java, C++, etc&#8230;). On peut voir une classe dans ces langages comme une fabrique dégénérée qui ne créerait qu&#8217;un seul type d&#8217;objet. On peut enregistrer ces classes dans une fabrique concrète qui crée les nombreux produits concrets en tant que variables, comme des prototypes. Ces classes vont créer de nouvelles instances à la place de la fabrique concrète. On définit une nouvelle fabrique en initialisant une instance de fabrique concrète contenant des classes de produits au lieu de sous-classer. Cette approche met à profit les caractéristiques de langage, au lieu de l&#8217;approche exactement basée sur Prototype, qui est indépendante du langage.Comme la fabrique basée sur Prototype dont on vient de parler en SmallTalk, la version basée sur les classes n&#8217;aura qu&#8217;une seule variable d&#8217;instance CatalogueDePièce, qui est un dictionnaire dont les clés sont les noms des pièces. Au lieu de conserver des prototypes à cloner, CatalogueDePièce enregistre les classes des produits. La méthode Créer ressemble maintenant à ça :

<div class="wp_syntax"><div class="code"><pre class="smalltalk">make: <span style="color: #00007f;">partName</span>
       ^ <span style="">&#40;</span><span style="color: #00007f;">partCatalog</span> at: <span style="color: #00007f;">partName</span><span style="">&#41;</span> new</pre></div></div>

</li>
<li>Définir des fabriques extensibles. Fabrique Abstraite définit généralement une méthode différente pour chaque type de produit qu&#8217;elle peut fabriquer. Les types de produits sont encodés dans les signatures de ces méthodes. Ajouter un nouveau type de produit demande la modification de l&#8217;interface de FabriqueAbstraite et de toutes ses sous-classes.Une manière de faire, plus flexible mais moins sûre, est d&#8217;ajouter un paramètre aux méthodes de création d&#8217;objets. Ce paramètre spécifie le type d&#8217;objet à créer. Cela peut être un identifiant de classe, un entier, une chaine de caractères, ou n&#8217;importe quoi d&#8217;autre qui identifie le type de produit. Dans les faits, avec cette approche, FabriqueAbstraite n&#8217;a besoin que d&#8217;une méthode Creer avec un paramètre indiquant le type d&#8217;objet à créer. C&#8217;est la technique utilisée dans la fabrique abstraite basée sur Prototype évoquée ci-dessus.Cette variation est plus simple à utiliser dans un langage typé dynamiquement comme SmallTalk plutôt que dans un langage typé statiquement comme C++.  Vous pouvez l&#8217;utiliser en C++ uniquement quand tous les objet ont la même classe abstraite de base, ou bien quand les produits peuvent être transtypés de manière sûre par le client qui les a demandés. La section Implémentation de la <a href="#">Fabrique</a> montre comment implémenter de telles méthodes paramétrées en C++.Mais même quand le transtypage n&#8217;est pas requis, il reste toujours un problème : tous les produits sont retournés au client avec la même interface abstraite que le type de retour. Si le client a besoin d&#8217;appeler une méthode spécifique à la sous-classe, elle ne sera pas accessible au travers de cette interface abstraite. Même si le client peut effectuer une conversion (i.e. avec dynamic_cast, en C++), ce n&#8217;est pas toujours faisable ou sûr, parce que la conversion peut échouer. C&#8217;est le compromis classique d&#8217;une interface hautement flexible et extensible.</li>
</ol>
<h3>Exemple de code</h3>
<p>On va appliquer le motif Fabrique Abstraite à la création de labyrinthes discutée au <a href="http://www.laumaille.net/2007/11/26/motifs-de-creation/">début de ce chapitre</a>.</p>
<p>La classe FabriqueDeLabyrinthe peut créer des composants de labyrinthes. Elle construit des pièces, des murs, et des portes entre les pièces. Elle peut être utilisée par un programme qui lit des plans de labyrinthe depuis un fichier, et construit le labyrinthe correspondant. Ou elle peut être utilisée par un programme qui construit des labyrinthes de manière aléatoire. Ces programmes construisant des labyrinthes prennent une FabriqueDeLabyrinthe en argument de manière à ce que le programmeur puisse spécifier les classes de pièces, de murs et de portes à construire.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> FabriqueDeLabyrinthe
    <span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Labyrinthe
        Return <span style="color: #FF8000;">New</span> Labyrinthe
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerMur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Mur
        Return <span style="color: #FF8000;">New</span> Mur
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerPiece<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> n <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Pièce
        Return <span style="color: #FF8000;">New</span> Pièce<span style="color: #000000;">&#40;</span>n<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerPorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> p1 <span style="color: #FF8000;">As</span> Pièce, <span style="color: #FF8000;">ByVal</span> p2 <span style="color: #FF8000;">As</span> Pièce<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Porte
        Return <span style="color: #FF8000;">New</span> Porte<span style="color: #000000;">&#40;</span>p1, p2<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Souvenez-vous de la fonction NouveauLabyrinthe qui construit un petit labyrinthe de deux pièces séparées par une porte. NouveauLabyrinthe code &#8220;en dur&#8221; les noms des classes, ce qui rend difficile la création de labyrinthes avec d&#8217;autres composants.</p>
<p>Voici une version de NouveauLabyrinthe qui va remédier à ce défaut en prenant une FabriqueDeLabyrinthe en paramètre :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> NouveauLabyrinthe<span style="color: #000000;">&#40;</span>fabrique <span style="color: #FF8000;">as</span> FabriqueDeLabyrinthe<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
    <span style="color: #0600FF;">Dim</span> oLabyrinthe <span style="color: #FF8000;">as</span> Labyrinthe = fabrique.<span style="color: #0000FF;">CreerLabyrinthe</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #0600FF;">Dim</span> oPiece1 = fabrique.<span style="color: #0000FF;">Pi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">Dim</span> oPiece2 = fabrique.<span style="color: #0000FF;">Pi</span>èce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">Dim</span> oPorte = fabrique.<span style="color: #0000FF;">Porte</span><span style="color: #000000;">&#40;</span>oPiece1, oPiece2<span style="color: #000000;">&#41;</span>    oLabyrinthe.<span style="color: #0000FF;">AjouterPiece</span><span style="color: #000000;">&#40;</span>oPiece1<span style="color: #000000;">&#41;</span>
    oLabyrinthe.<span style="color: #0000FF;">AjouterPiece</span><span style="color: #000000;">&#40;</span>oPiece2<span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Nord<span style="color: #000000;">&#41;</span> = fabrique.<span style="color: #0000FF;">Mur</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Sud<span style="color: #000000;">&#41;</span> = fabrique.<span style="color: #0000FF;">Mur</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Est<span style="color: #000000;">&#41;</span> = oPorte
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Ouest<span style="color: #000000;">&#41;</span> = fabrique.<span style="color: #0000FF;">Mur</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Nord<span style="color: #000000;">&#41;</span> = fabrique.<span style="color: #0000FF;">Mur</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Sud<span style="color: #000000;">&#41;</span> = fabrique.<span style="color: #0000FF;">Mur</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Est<span style="color: #000000;">&#41;</span> = fabrique.<span style="color: #0000FF;">Mur</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Ouest<span style="color: #000000;">&#41;</span> = oPorte
&nbsp;
    Return oLabyrinthe
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>On peut créer une FabriqueDeLabyrintheEnsorcellé en sous-classant FabriqueDeLabyrinthe. FabriqueDeLabyrintheEnsorcellé va surcharger différentes fonctions et retourner différentes sous-classes de Pièce, Mur, etc.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> FabriqueDeLabyrintheEnsorcellé
    <span style="color: #0600FF;">Inherits</span> FabriqueDeLabyrinthe
&nbsp;
    <span style="color: #FF8000;">Private</span> <span style="color: #0600FF;">Function</span> JetteUnSort<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Boolean</span>
        <span style="color: #0600FF;">Dim</span> oRnd <span style="color: #FF8000;">As</span> Random = <span style="color: #FF8000;">New</span> Random<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">CInt</span><span style="color: #000000;">&#40;</span>DateTime.<span style="color: #0600FF;">Now</span>.<span style="color: #0000FF;">Ticks</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #0600FF;">If</span> oRnd.<span style="color: #FF8000;">Next</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">0</span>, <span style="color: #FF0000;">5</span><span style="color: #000000;">&#41;</span> = <span style="color: #FF0000;">0</span> <span style="color: #FF8000;">Then</span>
            Return <span style="color: #0600FF;">True</span>
        <span style="color: #FF8000;">Else</span>
            Return <span style="color: #0600FF;">False</span>
        <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerPiece<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> n <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Pièce
        Return <span style="color: #FF8000;">New</span> PièceEnsorcellée<span style="color: #000000;">&#40;</span>n, JetteUnSort<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerPorte<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> p1 <span style="color: #FF8000;">As</span> Pièce, <span style="color: #FF8000;">ByVal</span> p2 <span style="color: #FF8000;">As</span> Pièce<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Porte
        Return <span style="color: #FF8000;">New</span> PorteAvecSort<span style="color: #000000;">&#40;</span>p1, p2<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Maintenant, supposons que l&#8217;on veuille faire un jeu de labyrinthe dans lequel les pièces peuvent contenir une bombe. Si la bombe explose, elle va endommager les murs. On peut créer une sous-classe de Pièce qui garde en mémoire si la pièce contient une bombe et si celle-ci a explosé ou non. Nous aurons également besoin d&#8217;une sous-classe Mur qui gardera une trace des dommages causés. Nous appellerons ces classes PiècePiégée et MurExplosé.</p>
<p>La dernière classa que nous définirons sera FabriqueDeLabyrinthePiégé, une sous-classe de FabriqueDeLabyrinthe qui s&#8217;assure que les murs sont de la classe MurExplosé et que les pièces sont de la classe PiècePiégée. FabriqueDeLabyrinthePiégée n&#8217;a besoin de surcharger que deux fonctions :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> FabriqueDeLabyrintheEnsorcellé
    <span style="color: #0600FF;">Inherits</span> FabriqueDeLabyrinthe
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerPiece<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> n <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Pièce
        Return <span style="color: #FF8000;">New</span> PiècePiégée<span style="color: #000000;">&#40;</span>n<span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
    <span style="color: #FF8000;">Public</span> Shared <span style="color: #0600FF;">Function</span> CreerMur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Mur
        Return <span style="color: #FF8000;">New</span> MurExplosé<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Pour construire un labyrinthe simple contenant des bombes, on va simplement appeler NouveauLabyrinthe avec une FabriqueDeLabyrinthePiégé.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Dim</span> jeu <span style="color: #FF8000;">as</span> JeuDuLabyrinthe
<span style="color: #0600FF;">Dim</span> fabrique <span style="color: #FF8000;">as</span> FabriqueDeLabyrinthePiégé
&nbsp;
jeu.<span style="color: #0000FF;">NouveauLabyrinthe</span><span style="color: #000000;">&#40;</span>fabrique<span style="color: #000000;">&#41;</span></pre></div></div>

<p>NouveauLabyrinthe peut aussi bien recevoir une instance de FabriqueDeLabyrintheEnsorcellé afin de construire des labyrinthes ensorcellés.</p>
<p>Notez bien que la FabriqueDeLabyrinthe est juste une collection de éthodes de fabrication. C&#8217;est la manière la plus courante d&#8217;implémenter le motif Fabrique Abstraite. Notez également que FabriqueDeLabyrinthe n&#8217;est pas une classe abstraite ; même si elle agit aussi bien en tant que FabriqueAbstraite au&#8217;en tant que FabriqueConcrète. C&#8217;est une autre implémentation courante du motif Fabrique Abstraite. Comme la FabriqueDeLabyrinthe est une classe concrète consistant entièrement en des méthodes de fabrication, il est très simple de faire une nouvelle FabriqueDeLabyrinthe en créant une sous-classe et en surchargeant uniquement les méthodes qui en ont besoin.</p>
<p>NouveauLabyrinthe utilise la propriété Cote des pièces pour spécifier leurs côtés. Si cette méthode crée des pièces avec une FabriqueDeLabyrinthePiégé, alors le labyrinthe sera fait d&#8217;objets PiècePiégée avec des objets MurExplosé sur les côtés. Si PiècePiégée doit accéder à un membre spécifique à la sous-classe MurExplosé, alors elle devra convertir les références à ses murs de Mur à MurExplosé. Ce sous-classement est sûr tant que les murs sont bien des MurExplosé, ce qui est garanti si les murs sont construit grâce à FabriqueDeLabyrinthePiégé.</p>
<p>Les langages typés dynamiquement comme SmallTalk ne requièrent pas de sous-classement bien sûr, mais ils pourraient produire des erreurs de runtime s&#8217;ils rencontrent un Mur alors qu&#8217;ils attendaient une sous-classe de Mur. L&#8217;utilisation de Fabrique Abstraite aide à la prévention de ces erreurs en s&#8217;assurant que seuls certains types de murs peuvent être créés.</p>
<p>Considérons une version SmallTalk de FabriqueDeLabyrinthe, une version avec juste une opération de création prenant le type d&#8217;objet à créer en paramètre. En outre, la fabrique concrète garde enregistre les classes de produits qu&#8217;elle crée.</p>
<p>Tout d&#8217;abord, on écrit un équivalent de NouveauLabyrinthe en SmallTalk :</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">createMaze: <span style="color: #00007f;">aFactory</span>  |<span style="color: #00007f;"> room1 room2 aDoor </span>|
&nbsp;
<span style="color: #00007f;">room1</span> := <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#room</span><span style="">&#41;</span> number: <span style="color: #00007f;"><span style="color: #7f0000;">1</span></span>.
&nbsp;
<span style="color: #00007f;">room2</span> := <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#room</span><span style="">&#41;</span> number: <span style="color: #00007f;"><span style="color: #7f0000;">2</span></span>.
&nbsp;
<span style="color: #00007f;">aDoor</span> := <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#door</span><span style="">&#41;</span> from: <span style="color: #00007f;">room1</span> to: <span style="color: #00007f;">room2</span>.
&nbsp;
<span style="color: #00007f;">room1</span> atSide: <span style="color: #7f0000;">#north</span> put: <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#wall</span><span style="">&#41;</span>.
&nbsp;
<span style="color: #00007f;">room1</span> atSide: <span style="color: #7f0000;">#east</span> put: <span style="color: #00007f;">aDoor</span>.
&nbsp;
<span style="color: #00007f;">room1</span> atSide: <span style="color: #7f0000;">#south</span> put: <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#wall</span><span style="">&#41;</span>.
&nbsp;
<span style="color: #00007f;">room1</span> atSide: <span style="color: #7f0000;">#west</span> put: <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#wall</span><span style="">&#41;</span>.
&nbsp;
<span style="color: #00007f;">room2</span> atSide: <span style="color: #7f0000;">#north</span> put: <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#wall</span><span style="">&#41;</span>.
&nbsp;
<span style="color: #00007f;">room2</span> atSide: <span style="color: #7f0000;">#east</span> put: <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#wall</span><span style="">&#41;</span>.
&nbsp;
<span style="color: #00007f;">room2</span> atSide: <span style="color: #7f0000;">#south</span> put: <span style="">&#40;</span><span style="color: #00007f;">aFactory</span> make: <span style="color: #7f0000;">#wall</span><span style="">&#41;</span>.
&nbsp;
<span style="color: #00007f;">room2</span> atSide: <span style="color: #7f0000;">#west</span> put: <span style="color: #00007f;">aDoor</span>.
&nbsp;
^ <span style="color: #0000ff;">Maze</span> new addRoom: <span style="color: #00007f;">room1</span>; addRoom: <span style="color: #00007f;">room2</span>; your<span style="color: #7f007f;">self</span></pre></div></div>

<p>Comme on l&#8217;a vu dans la section Implémentation, FabriqueDeLabyrinthe à seulement besoin d&#8217;une unique variable d&#8217;instance de CatalogueDePièce pour fournir un dictionnaire dont la clé est la classe de composant. Ainsi, voyons comment nous allons implémenter la méthode Construire :</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">make: <span style="color: #00007f;">partName</span>
  ^ <span style="">&#40;</span><span style="color: #00007f;">partCatalog</span> at: <span style="color: #00007f;">partName</span><span style="">&#41;</span> new</pre></div></div>

<p>Maintenant, on peut créer une FabriqueDeLabyrinthe et l&#8217;utiliser pour implémenter NouveauLabyrinthe. On vas créer la fabrique en utilisant une méthode NouvelleFabriqueDeLabyrinthe de la classe JeuDuLayrinthe.</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">createMazeFactory
  ^ <span style="">&#40;</span><span style="color: #0000ff;">MazeFactory</span> new
&nbsp;
addPart: <span style="color: #0000ff;">Wall</span> named: <span style="color: #7f0000;">#wall</span>;
&nbsp;
addPart: <span style="color: #0000ff;">Room</span> named: <span style="color: #7f0000;">#room</span>;
&nbsp;
addPart: <span style="color: #0000ff;">Door</span> named: <span style="color: #7f0000;">#door</span>;
&nbsp;
your<span style="color: #7f007f;">self</span><span style="">&#41;</span></pre></div></div>

<p>Une FabriqueDeLabyrinthePiégé ou une FabriqueDeLabyrintheEnsorcelé est créée en associant différentes classes aux clés. Par exemple, une FabriqueDeLabyrintheEnsorcelé pourrait être crée comme ceci :</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk">createMazeFactory
  ^ <span style="">&#40;</span><span style="color: #0000ff;">MazeFactory</span> new
&nbsp;
addPart: <span style="color: #0000ff;">Wall</span> named: <span style="color: #7f0000;">#wall</span>;
&nbsp;
addPart: <span style="color: #0000ff;">EnchantedRoom</span> named: <span style="color: #7f0000;">#room</span>;
&nbsp;
addPart: <span style="color: #0000ff;">DoorNeedingSpell</span> named: <span style="color: #7f0000;">#door</span>;
&nbsp;
your<span style="color: #7f007f;">self</span><span style="">&#41;</span></pre></div></div>

<h3>Utilisations connues</h3>
<p><a href="http://www.ivtools.org/ivtools/interviews.html">InterViews</a> utilise le suffixe &#8220;Kit&#8221; pour les classes FabriqueAbstraite. Il définit les fabriques abstraites WidgetKit et DialogKit pour générer des objets d&#8217;interface utilisateur avec un style spécifique. InterViews inclus également un LayouKit qui génère différents objets de composition, dépendants de la mise en page désirée. Par exemple, une mise en page horizontale va demander des objets de composition différents selon l&#8217;orientation du document (porttrait ou paysage).</p>
<p><a href="http://www.ivtools.org/ivtools/etplusplus.html">ET++</a> utilise la Fabrique Abstraite pour permettre la portabilité entre différents systèmes de fenêtrage (X Windows et SunView, par exemple). La classe abstraite de base WindowSystem définit l&#8217;interface pour créer des objets représentant les ressources d&#8217;un système de fenêtrage (MakeWindow, MakeFont, MakeColor, par exemple). Les classes concrètes dérivées implémentent les interfaces pour un système de fenêtrage spécifique. Lors de l&#8217;exécution, ET++ crée une instance d&#8217;une classe concrète dérivée de WindowSystem qui crée des objets concrets de ressources systèmes.</p>
<h3>Voir Aussi</h3>
<p>Les classes FabriqueAbstraite sont souvent implémentée avec le motif <a href="#">Fabrique</a>, mais elles peuvent également être implémentée avec <a href="#">Prototype</a>.</p>
<p>Une fabrique concrète est souvent un <a href="#">Singleton</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Développement de Site Web</title>
		<link>http://www.laumaille.net/2007/11/28/nouveau-contrat/</link>
		<comments>http://www.laumaille.net/2007/11/28/nouveau-contrat/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 10:11:43 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Divers]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/11/28/nouveau-contrat/</guid>
		<description><![CDATA[Bonjour bonjour !
Aujourd&#8217;hui, je voulais juste vous faire part d&#8217;un nouveau contrat que j&#8217;ai : un site web !!  Super, non ? Bon, c&#8217;est pas grand chose, juste un magazine gratuit local, ça fait 4 pages, avec un accueil, des archives, des partenaires et un formulaire de contact. Mais bon, c&#8217;est cool, ça faisait [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour bonjour !</p>
<p>Aujourd&#8217;hui, je voulais juste vous faire part d&#8217;un nouveau contrat que j&#8217;ai : un site web !!  Super, non ? Bon, c&#8217;est pas grand chose, juste un magazine gratuit local, ça fait 4 pages, avec un accueil, des archives, des partenaires et un formulaire de contact. Mais bon, c&#8217;est cool, ça faisait longtemps que j&#8217;avais pas bossé à mon compte&#8230; Et puis les dernières expériences s&#8217;étaient pas toutes super bien déroulées (des particuliers ou des associations, qui voulait des trucs fabuleux, mais si çà avait été gratuit ils auraitent préférés&#8230;). Alors que là, on sent que c&#8217;est du solide, plus réfléchi que la moyenne des clients.</p>
<p>Et puis, bon, faut dire que depuis que je fait du développement de site, je me suis vachement amélioré à force ! Pis je me suis mis au XHTML+CSS, avec des design de la mort&#8230; Enfin bref, c&#8217;est cool !</p>
<p>Je mettrais à jour le post quand le site sera fini&#8230; Histoire de mettre un petit lien ! <img src='http://www.laumaille.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>/* Edité le 30/11/2007 à 09:54 */</p>
<p>Et voilà une miniature du site qui vous emmenera directement le voir :</p>
<p><a href="http://www.rumeurs-mag.fr/" title="Rumeurs : Le Mag’"></a></p>
<p style="text-align: center"><a href="http://www.rumeurs-mag.fr/" title="Rumeurs : Le Mag’"><img src="http://www.laumaille.net/wp-content/uploads/2007/11/rumeurs-magfr.png" alt="Rumeurs : Le Mag’" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/11/28/nouveau-contrat/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Design Patterns : Motifs de Création</title>
		<link>http://www.laumaille.net/2007/11/26/motifs-de-creation/</link>
		<comments>http://www.laumaille.net/2007/11/26/motifs-de-creation/#comments</comments>
		<pubDate>Mon, 26 Nov 2007 16:31:45 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[Traduction]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/11/26/motifs-de-creation/</guid>
		<description><![CDATA[Cet article est le premier d&#8217;une longue série : j&#8217;attaque la traduction du livre sur les Design Patterns écrit par le Gang Of Four&#8230;
Les motifs de Création permettent l&#8217;abstraction du processus d&#8217;instanciation. Ils aident à rendre le système indépendant de la manière dont les objets sont créés, assemblés et représentés. Une classe de motif de [...]]]></description>
			<content:encoded><![CDATA[<p>Cet article est le premier d&#8217;une longue série : j&#8217;attaque la traduction du livre sur les Design Patterns écrit par le Gang Of Four&#8230;</p>
<p>Les motifs de Création permettent l&#8217;abstraction du processus d&#8217;instanciation. Ils aident à rendre le système indépendant de la manière dont les objets sont créés, assemblés et représentés. Une classe de motif de création utilise l&#8217;héritage afin de varier les classes devant être instanciées, tandis qu&#8217;un objet de motif de création va déléguer l&#8217;instanciation à un autre objet.</p>
<p>Les motifs de création gagnent en importance quand le système évolue afin de dépendre d&#8217;avantage de l&#8217;assemblage des objets plutôt que de l&#8217;héritage de classes. Durant cette transformation, on passe d&#8217;un code &#8220;en dur&#8221; avec un ensemble de comportements figés, vers un ensemble restreint de comportements fondamentaux qui peuvent être assemblés en de nombreux comportements plus complexes. Créer de cette manière des objets avec un comportement particulier demande plus qu&#8217;une simple instanciation de classe.</p>
<p><span id="more-21"></span></p>
<p>On retrouve deux thèmes réccurents dans ces motifs. Tout d&#8217;abord, ils encapsule la la visibilité de la classe concrète utilisée par le système. Ensuite, ils cachent la manière dont les instances de ces classes sont créées et mises ensemble. Tout ce que les systèmes connaissent des objets qu&#8217;ils utilisent, c&#8217;est leur interface telle qu&#8217;elle est définie par des classes abstraites. En conséquence, les motifs de création offrent une grande flexibilitésur <em>ce</em> qui est créé, <em>qui</em> le crée, <em>comment</em> c&#8217;est créé et <em>quand</em>. Ils permettent de configurer un système avec des objets &#8220;de production&#8221; variant énormément en termes de structures et de fonctionnalités. La configuration peut être statique (définie à la compilation) ou dynamique (au chargement).</p>
<p>Parfois, les motifs de création entrent en compétition. Par exemple, on trouve des cas où les motifs <a href="#">Prototype</a> ou <a href="http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/" title="Motif de Création : Fabrique Abstraite (Abstract Factory)">Fabrique Abstraite (Abstract Factory)</a> seraient tous les deux utiles. À d&#8217;autres moments, ils sont complémentaires : <a href="http://www.laumaille.net/2007/12/06/motifs-de-creation-monteur/" title="Motif de Création : Monteur (Builder)">Monteur (Builder)</a> peut utiliser d&#8217;autres motifs pour implémenter quel composant doit être créé. <a href="#">Prototype</a> peut utiliser <a href="#">Singleton</a> dans son implémentation.</p>
<p>Comme les motifs de création sont très proches les uns des autres, nous allons étudier les cinq ensemble afin de souligner leurs points communs et leurs différences. Nous allons également utiliser un exemple commun (construire un labyrinthe pour les besoins d&#8217;un jeu) afin d&#8217;illustrer leurs implémentation. Le labyrinthe et le jeu vont légèrement varier d&#8217;un motif à l&#8217;autre. Parfois, le jeu consistera simplement à trouver son chemin dans le labyrinthe ; dans ce cas le joueur n&#8217;aura probablement qu&#8217;une vue restreinte du labyrinthe. D&#8217;autres fois, le labyrinthe contiendra des énigmes à résoudre et des dangers à éviter, et ces jeux fourniront une carte de la partie du labyrinthe ayant été explorée.</p>
<p>On ignorera de nombreux détails sur ce qui peut être dans le labyrinthe, ou si le jeu a un ou plusieurs joueurs. Au lieu de cela, nous nous focaliserons sur la manière dont le labyrinthe est créé. On définit un labyrinthe comme un ensemble de pièces. Une pièce connaît son voisinage ; ses voisins peuvent être une autre pièce, un mur, ou une porte vers une autre pièce.</p>
<p>Les classes Pièce, Porte et Mur définissent les composants du labyrinthe utilisés dans tous nos exemples. Nous ne définirons que les parties de ces classes importantes pour créer un labyrinthe. Nous ignorerons les joueurs, les méthodes d&#8217;affichage et d&#8217;exploration du labyrinthe, et d&#8217;autres fonctionnalités importantes qui ne sont pas essentielles pour construire le labyrinthe.</p>
<p>Le schéma suivant montre les relations entre ces classes :</p>
<p><a href="http://www.laumaille.net/wp-content/uploads/2007/11/creationnal_1.gif" title="Schéma d’exemple" rel="thumbnail"></a></p>
<p style="text-align: center"><a href="http://www.laumaille.net/wp-content/uploads/2007/11/creationnal_1.gif" title="Schéma d’exemple" rel="thumbnail"><img src="http://www.laumaille.net/wp-content/uploads/2007/11/creationnal_1.thumbnail.gif" alt="Schéma d’exemple" /></a></p>
<p>Chaque pièce a quatre côtés. Nous utiliserons une énumération appelée Direction pour spécifier les faces nord, sud, est et ouest d&#8217;une pièce :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Enum</span> Direction
&nbsp;
  Nord
&nbsp;
  Sud
&nbsp;
  Est
&nbsp;
  Ouest
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Enum</span></pre></div></div>

<p>La classe ComposantLabyrinthe est la classe abstraite commune à tous les composants d&#8217;un labyrinthe. Pour simplifier l&#8217;exemple, ComposantLabyrinthe ne définit qu&#8217;une méthode, Entrer. Sons sens dépend de ce dans quoi vous entrez. Si vous entrez dans une pièce, votre localisation change. Si vous essayez d&#8217;entrer dans une portes, deux solutions : soit la porte est ouverte et vous changez de pièce, soit la porte est fermée et vous vous cognez le nez.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">MustInherit</span> <span style="color: #0600FF;">Class</span> ComposantLabyrinthe
&nbsp;
  <span style="color: #FF8000;">Public</span> MustOverride <span style="color: #0600FF;">Sub</span> Entrer<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Entrer fournit une simple base pour des actions de jeu plus sophistiquées. Par exemple, si vous êtes dans une pièce et que vous dites &#8220;Aller à l&#8217;Est&#8221;, le jeu peut déterminer simplement quel ComposantLabyrinthe est positionné à l&#8217;est, et appeler sa méthode Entrer. La méthode Entrer spécifique à la sous-classe va s&#8217;occuper de savoir si vous allez changer de pièce ou si vous allez avoir mal au nez. Dans un vrai jeu, Entrer pourrait prendre en argument l&#8217;objet Joueur en train de bouger. Pièce est la sous-classe concrète de ComposantLabyrinthe qui définit les relations-clés entre les différents composants du labyrinthe. Elle maintient les références aux autres composants et enregistre un numéro de pièce. Le numéro va identifier les pièces du labyrinthe.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> Pièce
&nbsp;
    <span style="color: #0600FF;">Inherits</span> ComposantLabyrinthe    <span style="color: #FF8000;">Private</span> _cotes<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">4</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> ComposantLabyrinthe
&nbsp;
    <span style="color: #FF8000;">Private</span> _numero <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #FF8000;">Property</span> Cote<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> <span style="color: #0600FF;">dir</span> <span style="color: #FF8000;">As</span> Direction<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> ComposantLabyrinthe
&nbsp;
        <span style="color: #FF8000;">Get</span>
&nbsp;
            Return _cotes<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">dir</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Get</span>
&nbsp;
        <span style="color: #FF8000;">Set</span><span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> value <span style="color: #FF8000;">As</span> ComposantLabyrinthe<span style="color: #000000;">&#41;</span>
&nbsp;
            _cotes<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">dir</span><span style="color: #000000;">&#41;</span> = value
&nbsp;
        <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Set</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Property</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">ReadOnly</span> <span style="color: #FF8000;">Property</span> Numero<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span>
&nbsp;
        <span style="color: #FF8000;">Get</span>
&nbsp;
            Return _numero
&nbsp;
        <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Get</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #FF8000;">Property</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> numero <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span>
&nbsp;
        _numero = numero
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> Overrides <span style="color: #0600FF;">Sub</span> Entrer<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">'...</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>Les classes suivantes représentent les murs et les portes.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> Mur
&nbsp;
    <span style="color: #0600FF;">Inherits</span> ComposantLabyrinthe    <span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">'...</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> Overrides <span style="color: #0600FF;">Sub</span> Entrer<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">'...</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span>
&nbsp;
<span style="color: #0600FF;">Class</span> Porte
&nbsp;
    <span style="color: #0600FF;">Inherits</span> ComposantLabyrinthe
&nbsp;
<span style="color: #FF8000;">Private</span> _piece1 <span style="color: #FF8000;">As</span> Pièce
&nbsp;
    <span style="color: #FF8000;">Private</span> _piece2 <span style="color: #FF8000;">As</span> Pièce
&nbsp;
    <span style="color: #FF8000;">Private</span> _ouverte <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Boolean</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> p1 <span style="color: #FF8000;">As</span> Pièce, <span style="color: #FF8000;">ByVal</span> p2 <span style="color: #FF8000;">As</span> Pièce<span style="color: #000000;">&#41;</span>
&nbsp;
        _piece1 = p1
&nbsp;
        _piece2 = p2
&nbsp;
        _ouverte = <span style="color: #0600FF;">False</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> AutreCote<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> p <span style="color: #FF8000;">As</span> Pièce<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Pièce
&nbsp;
        <span style="color: #0600FF;">If</span> p <span style="color: #FF8000;">Is</span> _piece1 <span style="color: #FF8000;">Then</span>
&nbsp;
            Return _piece2
&nbsp;
        ElseIf p <span style="color: #FF8000;">Is</span> _piece2 <span style="color: #FF8000;">Then</span>
&nbsp;
            Return _piece1
&nbsp;
        <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
&nbsp;
        Return <span style="color: #FF8000;">Nothing</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #FF8000;">Public</span> Overrides <span style="color: #0600FF;">Sub</span> Entrer<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">'...</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>On a besoin de connaître plus qu&#8217;une simple partie du labyrinthe. On définit en plus une classe Labyrinthe qui représente une collection de pièces. Labyrinthe peut aussi trouver une pièce donnée à partir de son numéro, en utilisant la méthode PieceNo.</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #0600FF;">Class</span> Labyrinthe
&nbsp;
    <span style="color: #FF8000;">Private</span> _pieces<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Pièce    <span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> <span style="color: #FF8000;">New</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">'...</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Sub</span> AjouterPiece<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> p <span style="color: #FF8000;">As</span> Pièce<span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">'...</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span>
&nbsp;
<span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> PieceNo<span style="color: #000000;">&#40;</span><span style="color: #FF8000;">ByVal</span> n <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Integer</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">As</span> Pièce
&nbsp;
        <span style="color: #FF8000;">For</span> <span style="color: #0600FF;">Each</span> p <span style="color: #FF8000;">As</span> Pièce In _pieces
&nbsp;
            <span style="color: #0600FF;">If</span> p.<span style="color: #0000FF;">Numero</span> = n <span style="color: #FF8000;">Then</span>
&nbsp;
                Return p
&nbsp;
            <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
&nbsp;
        <span style="color: #FF8000;">Next</span> p
&nbsp;
        Return <span style="color: #FF8000;">Nothing</span>
&nbsp;
    <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span>
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></pre></div></div>

<p>PieceNo peut faire une recherche par dictionnaire, table de hashage, ou un simple tableau comme ci-dessus. On ne se préoccupe pas de ces détails ici. Au lieu de ça, nous allons nous focaliser sur la manière de spécifier les composants d&#8217;un objet Labyrinthe.</p>
<p>Une autre classe à définir va être JeuDuLabyrinthe, qui va créer le labyrinthe. Une manière directe de créer le labyrinthe va être de spécifier une série d&#8217;opérations pour ajouter des composants à un labyrinthe et les connecter entre eux. Par exemple, la function suivante va créer un labyrinthe composé de deux pièces avec une porte entre les deux :</p>

<div class="wp_syntax"><div class="code"><pre class="vbnet"><span style="color: #FF8000;">Public</span> <span style="color: #0600FF;">Function</span> NouveauLabyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">as</span> Labyrinthe
&nbsp;
    <span style="color: #0600FF;">Dim</span> oLabyrinthe <span style="color: #FF8000;">as</span> Labyrinthe = <span style="color: #FF8000;">New</span> Labyrinthe<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #0600FF;">Dim</span> oPiece1 = <span style="color: #FF8000;">New</span> Pièce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #0600FF;">Dim</span> oPiece2 = <span style="color: #FF8000;">New</span> Pièce<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #0600FF;">Dim</span> oPorte = <span style="color: #FF8000;">New</span> Porte<span style="color: #000000;">&#40;</span>oPiece1, oPiece2<span style="color: #000000;">&#41;</span>    oLabyrinthe.<span style="color: #0000FF;">AjouterPiece</span><span style="color: #000000;">&#40;</span>oPiece1<span style="color: #000000;">&#41;</span>
&nbsp;
    oLabyrinthe.<span style="color: #0000FF;">AjouterPiece</span><span style="color: #000000;">&#40;</span>oPiece2<span style="color: #000000;">&#41;</span>
&nbsp;
oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Nord<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Sud<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Est<span style="color: #000000;">&#41;</span> = oPorte
&nbsp;
    oPiece1.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Ouest<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Nord<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Sud<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Est<span style="color: #000000;">&#41;</span> = <span style="color: #FF8000;">New</span> Mur<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
    oPiece2.<span style="color: #0000FF;">Cote</span><span style="color: #000000;">&#40;</span>Ouest<span style="color: #000000;">&#41;</span> = oPorte
&nbsp;
Return oLabyrinthe
&nbsp;
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

<p>Cette fonction est quelque peu compliquée si l&#8217;on considère qu&#8217;elle ne fait que créer un labyrinthe à deux pièces. On pourrait évidemment simplifier cela. Par exemple, le constructeur de Pièce pourrait initialiser les côtés par un mur dès le départ. Mais ça ne ferait que déplacer le code ailleurs. Le vrai problème avec cette fonction ne vient pas de sa taille mais plutôt de son manque de flexibilité. On code en dur le schéma du labyrinthe. Changer de schéma signifie changer de fonction, soit en la surchargeant (ce qui implique de tout réimplémenter) soit en la modifiant en partie (ce qui est générateur d&#8217;erreur et empêche la réutilisation).</p>
<p>Les motifs de création montrent comment rendre ceci plus flexible, mais pas nécessairement plus court. En particulier, ils vont rendre simple le changement de classes définissant les composants d&#8217;un labyrinthe.</p>
<p>Supposons que vous vouliez réutiliser un schéma de labyrinthe existant pour un nouveau jeu contenant (entre autre) des labyrinthes ensorcellés. Le jeu de labyrinthe ensorcellé va avoir de nouveaux type de composants, comme PorteAvecSort, une porte verrouillée qui ne peut être ouverte qu&#8217;en utilisant un sort ; et PièceEnsorcelée, une pièce qui peut contenir des articles non conventionnels, comme des sorts ou des clés magiques. Comment pourriez-vous modifier simplement CreerLabyrinthe afin que cette fonction crée des labyrinthes avec ces nouveaux objets ?</p>
<p>Dans ce cas, le plus gros obstacle au changement résulte de l&#8217;appel &#8220;en dur&#8221; des classes à instancier. Les motifs de création fournissent des différentes manières de supprimer les références explicites aux classes concrètes du code devant les instancier :</p>
<ul>
<li>Si NouveauLabyrinthe fait appelle à des fonctions virtuelles au lieu des constructeurs pour créer les pièces, les murs, et les portes requises, alors vous pourrez changer les classes instanciées en construisant une sous-classe de JeuDuLabyrinthe et en redéfinissant ces fonctions virtuelles. Cette approche est un exemple du motif <a href="#">Fabrique</a>.</li>
<li>Si on passe en paramètre à NouveauLabyrinthe un objet utilisé pour créer les pièces, les murs et les portes, alors on peut changer les classes pièces, murs et portes à utiliser en passant un paramètre différent. C&#8217;est un exemple du motif <a href="http://www.laumaille.net/2007/12/04/motifs-de-creation-fabrique-abstraite/" title="Motif de Création : Fabrique Abstraite (Abstract Factory)">Fabrique Abstraite (Abstract Factory)</a></li>
<li>Si NouveauLabyrinthe reçoit un objet qui peut créer entièrement un nouveau labyrinthe en utilisant des fonctions pour ajouter les pièces, les portes et les murs au labyrinthe qu&#8217;il construit, alors vous pourrez changer des parties du labyrinthe, où la manière dont il est monté. C&#8217;est un exemple du motif <a href="http://www.laumaille.net/2007/12/06/motifs-de-creation-monteur/" title="Motif de Création : Monteur (Builder)">Monteur (Builder)</a>.</li>
<li>Si NouveauLabyrinthe est paramétrés par de nombreux objets prototypés pièce, portes et murs, qu&#8217;il copie et ajoute au labyrinthe, alors vous pourrez changer la composition du labyrinthe en remplaçant ces objets prototypés par d&#8217;autres. C&#8217;est un exemple du motif <a href="#">Prototype</a>.</li>
</ul>
<p>Le motif de création restant, <a href="#">Singleton</a>, permet de s&#8217;assurer qu&#8217;il n&#8217;existe qu&#8217;un seul labyrinthe par jeu, et que chaque objet jeu a accès à lui (sans recourir à une variable globale ou une fonction globale). Singleton permet aussi facilement d&#8217;étendre ou de remplacer le labyrinthe sans toucher au code existant.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/11/26/motifs-de-creation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>FIR/RIR : Méthodes de remplacement de texte par une image</title>
		<link>http://www.laumaille.net/2007/11/26/firrir-methodes-de-remplacement-de-texte-par-une-image/</link>
		<comments>http://www.laumaille.net/2007/11/26/firrir-methodes-de-remplacement-de-texte-par-une-image/#comments</comments>
		<pubDate>Mon, 26 Nov 2007 15:06:36 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Traduction]]></category>

		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/11/26/firrir-methodes-de-remplacement-de-texte-par-une-image/</guid>
		<description><![CDATA[Article de Dave Shea, tiré de son blog, traduit par mes soins.
Cet article nous donne des techniques pour remplacer du texte dans une page web (un titre, un lien, etc&#8230;) par une image, tout en restant lisible par un navigateur pour malvoyant, ou un navigateur ayant désactivé le css, ou les images, ou les deux.
Designer [...]]]></description>
			<content:encoded><![CDATA[<p>Article de <strong>Dave Shea</strong>, tiré de son <a href="http://www.mezzoblue.com/tests/revised-image-replacement/">blog</a>, traduit par mes soins.</p>
<p>Cet article nous donne des techniques pour remplacer du texte dans une page web (un titre, un lien, etc&#8230;) par une image, tout en restant lisible par un navigateur pour malvoyant, ou un navigateur ayant désactivé le css, ou les images, ou les deux.</p>
<p>Designer graphique dont le travail a été largement reconnu et récompensé par de nombreux prix, membre du Web Standard Project (WaSP), <strong>Dave Shea</strong> est le créateur et le &#8220;jardinier&#8221; du site CSS Zen Garden. En plus de son poste à la tête de la Bright Creative, une agence de design web, il écrit régulièrement sur tout ce qui a trait au Web sur son site <a href="http://www.mezzoblue.com">mezzoblue.com</a>.</p>
<p><span id="more-16"></span></p>
<p>Problématique : le remplacement doit résoudre les problèmes des navigateurs pour non-voyants, ainsi que le problème du &#8220;image off, css on&#8221;. On espère également qu&#8217;une solution sera trouvée pour réduire le nombre de balises <code>&lt;span&gt;</code> vides requises.</p>
<h2>FIR Classique (Fahrner Image Replacement)</h2>
<p>En utilisant le <a href="http://www.stopdesign.com/also/articles/replace_text/">tutorial original</a> de Doug Bowman, on entoure le texte de balises <code>&lt;span&gt;</code> vides en les cachant avec <code>display: none;</code>.</p>
<p><strong>Problème :</strong> la plupart des navigateurs pour non-voyants ne liront pas le texte puisqu&#8217;il n&#8217;est pas affiché, rien n&#8217;apparaît non plus dans le cas du &#8220;image off, css on&#8221;, et on a besoin de <code>&lt;span&gt;</code> sans aucune fonction sémantiques.</p>
<h3 style="width: 329px; height: 25px; background-image: url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif')"><span style="display: none">Revised Image Replacement</span></h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;span<span style="font-weight: bold; color: black;">&gt;</span></span></span>Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/span<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">background-image</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#header</span> span <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">none</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>Remplacement avec une image d&#8217;1px</h2>
<p>La <a href="http://www.homelesspixel.de/rt/textimage.html">solution</a> de Radu Darvas est d&#8217;ajouter une image GIF transparente, de 1px par 1px, pour afficher le texte définit dans l&#8217;attribut <code>alt</code>.</p>
<p><strong>Problème :</strong> un élément sans fonction sémentique est encore ajouté à la page.</p>
<h3 style="width: 329px; height: 25px; background-image: url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif')"><img src="http://www.laumaille.net/wp-content/uploads/2007/11/shim.gif" alt="Revised Image Replacement" /><span style="display: none">Revised Image Replacement</span></h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;img</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;shim.gif&quot;</span> <span style="color: #000066;">alt</span>=<span style="color: #ff0000;">&quot;Revised Image Replacement&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;span<span style="font-weight: bold; color: black;">&gt;</span></span></span>Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/span<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">background-image</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#header</span> span <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">none</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Radu</h2>
<p>Radu a aussi conçu une méthode nécessitant le positionnement d&#8217;une marge pour cacher le texte. En théorie similaire à la méthode de Phark décrite plus bas, cette solution fonctionne sous IE5.</p>
<p><strong>Problème :</strong> ne résoud pas le problème du &#8220;image off, css on&#8221;.</p>
<h3 style="margin: 0pt 0pt 0pt -2000px; background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') no-repeat scroll right top; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 2329px; height: 25px">Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #000000; font-weight: bold;">top</span> <span style="color: #000000; font-weight: bold;">right</span>;
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">2329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">margin</span>: <span style="color: #933;">0</span> <span style="color: #933;">0</span> <span style="color: #933;">0</span> -<span style="color: #933;">2000px</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Leahy/Langridge</h2>
<p><a href="http://www.moronicbajebus.com/playground/cssplay/image-replacement/">Seamus Leahy</a> et <a href="http://www.kryogenix.org/code/browser/lir/">Stuart Langridge</a> ont tous les deux découvert une méthode qui autorise à retirer le <code>&lt;span&gt;</code> et restore, en théorie (bien que ce ne soit pas confirmé) l&#8217;accessibilité grâce à <code>overflow: hidden</code>.</p>
<p><strong>Problème :</strong> rien n&#8217;apparaît dans le cas du &#8220;image off, css on&#8221;, et il faut un hack pour que cela fonctionne sous IE5.</p>
<h3 style="padding: 25px 0pt 0pt; overflow: hidden; background-image: url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif'); background-repeat: no-repeat; height: 0px ! important">Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">padding</span>: <span style="color: #933;">25px</span> <span style="color: #933;">0</span> <span style="color: #933;">0</span> <span style="color: #933;">0</span>;
  <span style="color: #000000; font-weight: bold;">overflow</span>: <span style="color: #993333;">hidden</span>;
  <span style="color: #000000; font-weight: bold;">background-image</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000000; font-weight: bold;">background-repeat</span>: <span style="color: #993333;">no-repeat</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">0px</span> !important;
  <span style="color: #000000; font-weight: bold;">height</span> <span style="color: #808080; font-style: italic;">/**/</span><span style="color: #3333ff;">:<span style="color: #933;">25px</span></span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Phark</h2>
<p>Simplifiant grandement la méthode Leahy/Langridge, Mike Rundle (<a href="http://phark.net/">phark.net</a>) offre une solution qui utilise <code>text-indent</code> pour cacher le texte. Cette technique fonctionne sous JAWS, ce qui résoud le problème d&#8217;accessibilité.</p>
<p><strong>Problème :</strong> rien ne s&#8217;affiche dans le scénario &#8220;image off, css on&#8221;, et ne fonctionne pas sous IE5.</p>
<h3 style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') repeat scroll 0% 50%; overflow: hidden; width: 329px; height: 25px; text-indent: -100em; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">text-indent</span>: -<span style="color: #933;">100em</span>;
  <span style="color: #000000; font-weight: bold;">overflow</span>: <span style="color: #993333;">hidden</span>;
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Phark revisitée</h2>
<p>Des investigations plus poussées ont révélé des faiblesses dans la méthode précédente, avec les scrollbars sous Safari et avec la casse sous IE5.</p>
<p><strong>Problème :</strong> ne résoud pas le &#8220;image off, css on&#8221;.</p>
<h3 style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') no-repeat scroll 0% 50%; width: 329px; height: 25px; text-indent: -5000px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">text-indent</span>: -<span style="color: #933;">5000px</span>;
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Dwyer</h2>
<p>Un truc inattendu qui nous vient de Leon Dwyer, basé sur le FIR classique. Marche apparemment pour tous les navigateurs connus à ce jours, dont les navigateurs pour non-voyants.</p>
<p><strong>Problème :</strong> ne résoud pas le problème du &#8220;image off, css on&#8221;, et requiert toujours une balise <code>&lt;span&gt;</code> supplémentaire.</p>
<h3 style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 329px; height: 25px"><span style="overflow: hidden; width: 0pt; height: 0pt; display: block">Revised Image Replacement</span></h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;span<span style="font-weight: bold; color: black;">&gt;</span></span></span>Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/span<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">background-image</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#header</span> span <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">block</span>;
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">0</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">0</span>;
  <span style="color: #000000; font-weight: bold;">overflow</span>: <span style="color: #993333;">hidden</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Gilder/Levin</h2>
<p><a href="http://blog.tom.me.uk/2003/08/07/">Tom Gilder</a> et <a href="http://levin.grundeis.net/files/20030809/alternatefir.html">Levin Alexander</a> proposent une variation supplémentaire pour régler, théoriquement, le problème de l&#8217;accessibilité (reste à vérifier, mais il est pratiquement sûr que ça fonctionne sous JAWS), et permet au texte d&#8217;être visible si on est dans un schéma &#8220;image off, css on&#8221;.</p>
<p><strong>Problème :</strong> une balise <code>&lt;span&gt;</code> en trop, et une image transparente ne cachera pas le texte.</p>
<p>(Note : on a doublé l&#8217;exemple, pour montrer le problème des images transparentes.)</p>
<h3 style="width: 329px; height: 25px; position: relative"><span style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') no-repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; position: absolute; width: 100%; height: 100%"></span>Revised Image Replacement</h3>
<h3 style="width: 329px; height: 25px; position: relative"><span style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-transparent.gif') no-repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; position: absolute; width: 100%; height: 100%"></span>Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;span<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/span<span style="font-weight: bold; color: black;">&gt;</span></span></span>Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">position</span>: <span style="color: #993333;">relative</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#header</span> span <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span>;
  <span style="color: #000000; font-weight: bold;">position</span>: <span style="color: #993333;">absolute</span>;
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;"><span style="color: #933;">100</span>%</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;"><span style="color: #933;">100</span>%</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>La méthode Lindsay</h2>
<p><a href="http://www.maxdesign.com.au/presentation/headings-as-images/index.cfm#option4">Russ Weakley</a> écrit qu&#8217;en mettant une taille de police minuscule, de 1px, et en faisant coïncider les couleurs de la police et de l&#8217;arrière plan, on n&#8217;a plus besoin de cacher le texte.</p>
<p><strong>Problème :</strong> ne résoud pas le &#8220;image off, css on&#8221;, et ne marche que pour des images d&#8217;arrière-plan unies.</p>
<h3 style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') no-repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 329px; height: 25px; font-size: 1px; color: #c6dbf7">Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'sample-opaque.gif'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span>;
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">font-size</span>: <span style="color: #933;">1px</span>;
  <span style="color: #000000; font-weight: bold;">color</span>: <span style="color: #cc00cc;">#xxxxxx</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h2>Le perfectionnement de Shea</h2>
<p>Au final, quelle que soit la méthode utilisée, vous perdez le texte visible au survol de l&#8217;image, que vous ou vos utilisateurs aviez l&#8217;habitude de voir. Techniquement, vous ne devriez pas compter dessus de toute manière, puisque <code>title</code> est beaucoup plus approprié pour les &#8220;tool-tips&#8221;. Mais en ajoutant un <code>title</code> à votre <code>header</code>, vous pouvez retrouver ce petit effet sur votre site.</p>
<h3 style="width: 329px; height: 25px; position: relative" title="Revised Image Replacement"><span style="background: transparent url('http://www.laumaille.net/wp-content/uploads/2007/11/sample-opaque.gif') no-repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; position: absolute; width: 100%; height: 100%"></span>Revised Image Replacement</h3>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;h3</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Revised Image Replacement&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;span<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/span<span style="font-weight: bold; color: black;">&gt;</span></span></span>Revised Image Replacement<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/h3<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#header</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">329px</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">25px</span>;
  <span style="color: #000000; font-weight: bold;">position</span>: <span style="color: #993333;">relative</span>;
<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#header</span> span <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">sample-opaque<span style="color: #6666ff;">.gif</span></span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span>;
  <span style="color: #000000; font-weight: bold;">position</span>: <span style="color: #993333;">absolute</span>;
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;"><span style="color: #933;">100</span>%</span>;
  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;"><span style="color: #933;">100</span>%</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/11/26/firrir-methodes-de-remplacement-de-texte-par-une-image/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sprites CSS : La mort du découpage d&#8217;image</title>
		<link>http://www.laumaille.net/2007/11/23/sprites-css-la-mort-du-decoupage-dimage/</link>
		<comments>http://www.laumaille.net/2007/11/23/sprites-css-la-mort-du-decoupage-dimage/#comments</comments>
		<pubDate>Fri, 23 Nov 2007 14:01:29 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Traduction]]></category>

		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/2007/11/23/sprites-css-la-mort-du-decoupage-dimage/</guid>
		<description><![CDATA[Article de Dave Shea paru en version originale sur le site www.alistapart.com, traduction par mes soins.
Designer graphique dont le travail a été largement reconnu et récompensé par de nombreux prix, membre du Web Standard Project (WaSP), Dave Shea est le créateur et le &#8220;jardinier&#8221; du site CSS Zen Garden. En plus de son poste à [...]]]></description>
			<content:encoded><![CDATA[<p>Article de <strong>Dave Shea</strong> paru en version originale sur le site <a href="http://www.alistapart.com/articles/sprites/">www.alistapart.com</a>, traduction par mes soins.</p>
<p>Designer graphique dont le travail a été largement reconnu et récompensé par de nombreux prix, membre du Web Standard Project (WaSP), <strong>Dave Shea</strong> est le créateur et le &#8220;jardinier&#8221; du site CSS Zen Garden. En plus de son poste à la tête de la Bright Creative, une agence de design web, il écrit régulièrement sur tout ce qui a trait au Web sur son site <a href="http://www.mezzoblue.com">mezzoblue.com</a>.</p>
<p><span id="more-3"></span></p>
<p>Quand les jeux videos étaient encore marrant (on parle ici des jours de gloire du 8-bits), les graphismes étaient beaucoup plus simple par nécéssité. Les personnages 2D et les paysages étaient dessinés individuellement, tout comme dans l&#8217;art numérique résurgent aujourd&#8217;hui. Des centaines, et plus tard des milliers de petits graphiques appelés &#8220;Sprites&#8221; étaient les briques de tout élément visuel d&#8217;un jeu.</p>
<p><img src="http://www.laumaille.net/wp-content/uploads/2007/11/sprites.gif" alt="Exemple de Sprites" /></p>
<p>À mesure que la complexité de jeu augmentait, les techniques se sont développées pour contrôler la multitude de sprites tout en préservant la fluidité du jeu. Une de ces variations fut de dessiner tous les sprites dans une image unique, puis de découper et positionner à la demande chaque graphique afin de les dessiner dans le bon ordre à l&#8217;écran.</p>
<h2>Quel est le rapport avec le web ?</h2>
<p>Tout ce qui est dépassé redevient utile, et malgré l&#8217;essort des jeux 3D, qui a rendu obsolète les cartes de sprites, l&#8217;émergence des appareils mobiles et de leurs capacités limitées aux jeux 2D a remis ces même cartes de sprites au goût du jour. Et maintenant, avec un peu de maths et beaucoup de CSS, on va reprendre la base de ce concept et l&#8217;appliquer au monde du web design.</p>
<p>En fait, nous allons remplacer le découpage et le tronçonnage d&#8217;image &#8220;vieille-école&#8221; (et tout le JavaScript qui va avec) par une solution en CSS. Et grâce à la manière dont fonctionne le CSS, on peut aller encore plus loin : en construisant une grille d&#8217;images et en concevant un moyen d&#8217;afficher individuellement chaque cellule de cette grille, on peut stocker tous les boutons/items de navigation/ce qu&#8217;on veut dans un seul fichier image principal, ou bien des images &#8220;avant/après&#8221; pour des liens.</p>
<h2>Comment fonctionnent les Sprites CSS ?</h2>
<p>Evidemment, les outils de base pour faire fonctionner tout ça sont déjà implémentés en CSS, il suffit juste d&#8217;un peu d&#8217;imagination.</p>
<p>Commençons par l&#8217;image principale en elle-même. On va diviser un rectangle en quatre zone. Vous remarquerez que dans cette <a href="http://www.laumaille.net/wp-content/uploads/2007/11/test-3.jpg">image</a> on met les états &#8220;avant&#8221; en haut, et les états &#8220;après&#8221; (<code>:hover</code>) juste en dessous. Il n&#8217;y a pas de division franche entre les différents liens pour le moments, alors imaginez pour l&#8217;instant que chaque partie de texte est un lien. (Pour des raisons de simplicité, on continuera de se référer aux images de lien comme image &#8220;avant&#8221;, et aux images d&#8217;état <code>:hover</code> comme image &#8220;après&#8221; pour le reste de l&#8217;article. Il est possible d&#8217;étendre cette méthode aux états <code>:active</code>, <code>:focus</code> et <code>:visited</code>, mais nous n&#8217;irons pas jusque là.)</p>
<p>Les personnes familières de la technique du <a href="http://wellstyled.com/css-nopreload-rollovers.html"> Rollover CSS</a> de Petr Stanicek’s (Pixy) voient déjà où l&#8217;on veut en venir. Cet article doit beaucoup à l&#8217;exemple de Pixy sur la fonction basique dont nous allons parler. Mais n&#8217;allons pas trop vite.</p>
<p>Voyons le code HTML. Tout bon truc CSS permet de poser une couche graphique sur un bloc de code propre, et cette technique ne fait pas exception :</p>

<div class="wp_syntax"><div class="code"><pre>&lt;ul id=&quot;skyline&quot;&gt;
&lt;li id=&quot;panel1b&quot;&gt;&lt;a href=&quot;#1&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;panel2b&quot;&gt;&lt;a href=&quot;#2&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;panel3b&quot;&gt;&lt;a href=&quot;#3&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;panel4b&quot;&gt;&lt;a href=&quot;#4&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</pre></div></div>

<p>Ce code va servir de base pour notre exemple. Léger, des balises simples qui s&#8217;affichent bien en environnement dégradé (ancien navigateur ou navigateur sans CSS), c&#8217;est là toute sa force, et cette tendance est bonne pour le métier. C&#8217;est un idéal à viser. (On ne gèrera pas le texte des liens dans cet article. Vous appliquerez plus tard votre technique favorite de <a href="http://www.mezzoblue.com/tests/revised-image-replacement/">remplacement de texte par une image</a> pour cacher le texte que vous ajouterez.</p>
<h2>Appliquer le CSS</h2>
<p>Après ce premier bloc basique, il est temps de construire le CSS. Un petit mot avant de commencer : en raison d&#8217;un problème d&#8217;IE, on posera l&#8217;image &#8220;après&#8221; par dessus l&#8217;image &#8220;avant&#8221;, au lieu de remplacer l&#8217;une par l&#8217;autre. Le résultat ne comportera aucune différence si on aligne précisemment les images, mais cette méthode permet d&#8217;éviter un effet de scintillement.</p>

<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#skyline</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">400px</span>;height: <span style="color: #933;">200px</span>;
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">test<span style="color: #933;">-3</span><span style="color: #6666ff;">.jpg</span></span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000000; font-weight: bold;">margin</span>: <span style="color: #933;">10px</span> <span style="color: #993333;">auto</span>;
  <span style="color: #000000; font-weight: bold;">padding</span>: <span style="color: #933;">0</span>;
  <span style="color: #000000; font-weight: bold;">position</span>: <span style="color: #993333;">relative</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#skyline</span> li <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">margin</span>: <span style="color: #933;">0</span>;
  <span style="color: #000000; font-weight: bold;">padding</span>: <span style="color: #933;">0</span>;
  <span style="color: #000000; font-weight: bold;">list-style</span>: <span style="color: #993333;">none</span>;
  <span style="color: #000000; font-weight: bold;">position</span>: <span style="color: #993333;">absolute</span>;
  <span style="color: #000000; font-weight: bold;">top</span>: <span style="color: #933;">0</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#skyline</span> li, <span style="color: #cc00cc;">#skyline</span> a <span style="color: #66cc66;">&#123;</span>  <span style="color: #000000; font-weight: bold;">height</span>: <span style="color: #933;">200px</span>;
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">block</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Contrairement à ce qu&#8217;on pourrait penser, on n&#8217;affecte pas l&#8217;image &#8220;avant&#8221; aux liens, mais plutôt à la balise <code>&lt;ul&gt;</code>. Vous comprendrez pourquoi dans un moment.</p>
<p>Le bout de CSS dans l&#8217;exemple ci-dessus règle des choses comme la dimension du bloc <code>#skyline</code> et des éléments de liste, le positionnement des éléments de liste, et retire les puces de la liste.</p>
<p>On laisse les liens en leur état de blocs vides et transparents (mais aux dimensions spécifiques) pour déclencher le lien, et on les positionne en utilisant les conteneurs <code>&lt;li&gt;</code>. Si on positionnait les liens eux même en ignorant les <code>&lt;li&gt;</code>, cela déclencherait des erreurs dans les navigateurs les plus anciens, donc on va éviter ça.</p>
<h2>Positionner les liens</h2>
<p>Les balises <code>&lt;li&gt;</code> sont positionné en absolu, alors pourquoi ne s&#8217;affichent elles pas en haut de la fenêtre du navigateur ? Eh bien, une des propriétés, bizarre mais très utile, des éléments positionnés est que tous leurs descendant vont baser leur position absolu non pas sur la fenêtre du navigateur, mais sur leur premier ancêtre positionné. Le résultat est que tant qu&#8217;on applique une <code>position: relative;</code> à <code>#skyline</code>, alors la position absolu des balises <code>&lt;li&gt;</code> sera calculée à partir du coin en haut à gauche de <code>#skyline</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#panel1b</span> <span style="color: #66cc66;">&#123;</span><span style="color: #000000; font-weight: bold;">left</span>: <span style="color: #933;">0</span>; <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">95px</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#panel2b</span> <span style="color: #66cc66;">&#123;</span><span style="color: #000000; font-weight: bold;">left</span>: <span style="color: #933;">96px</span>; <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">75px</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#panel3b</span> <span style="color: #66cc66;">&#123;</span><span style="color: #000000; font-weight: bold;">left</span>: <span style="color: #933;">172px</span>; <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">110px</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#panel4b</span> <span style="color: #66cc66;">&#123;</span><span style="color: #000000; font-weight: bold;">left</span>: <span style="color: #933;">283px</span>; <span style="color: #000000; font-weight: bold;">width</span>: <span style="color: #933;">117px</span>;<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Ainsi, <code>#panel1b</code> est positionné contre le bord gauche de <code>#skyline</code>, <code>#panel2b</code> est positionné à 96px du bord gauche de <code>#skyline</code>, et ainsi de suite. Dans le listing précédent, on a assigné la valeur <code>display: block;</code> aux liens, ainsi que la même hauteur qu&#8217;aux balises <code>&lt;li&gt;</code>, si bien que les liens vont totalement remplir ces balises <code>&lt;li&gt;</code>, ce qui est exactement ce qu&#8217;on veut.</p>
<p>Nous avons maintenant une image basique découpée en liens, mais pas d&#8217;état <code>:hover</code>. Regardez cet <a href="http://www.laumaille.net/wp-content/uploads/2007/11/image1.html">exemple</a>. Il sera sûrement plus simple de constater le résultat en activant <a href="http://www.laumaille.net/wp-content/uploads/2007/11/image1a.html">les bordures</a>.</p>
<h2>Hover</h2>
<p>Par le passé nous aurions mis un peu de JavaScript afin d&#8217;échanger les images &#8220;avant/après&#8221;. Au lieu de cela, les deux états étant dans la même image, tout ce qu&#8217;il nous faut trouver est un moyen de retirer de manière sélective chacun de nos états pour le lien approprié.</p>
<p>Si on applique l&#8217;image principale à l&#8217;état <code>:hover</code> sans valeurs additionnelles, on affichera uniquement le coin supérieur gauche (ce qui n&#8217;est pas ce qu&#8217;on veut) coupé à la taille du lien (ce qui est ce qu&#8217;on veut). On doit donc modifier la position de l&#8217;image d&#8217;une manière ou d&#8217;une autre.</p>
<p>On doit y arriver avec les seules valeurs connues en pixels ; un peu de maths devraient nous permettre de décaller cette image de fond à la fois horizontalement et verticalement afin de ne montrer que la partie correspondant à l&#8217;état &#8220;après&#8221;.</p>
<p>C&#8217;est exactement ce qu&#8217;on fait :</p>

<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #cc00cc;">#panel1b</span> a<span style="color: #3333ff;">:hover</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">test<span style="color: #933;">-3</span><span style="color: #6666ff;">.jpg</span></span><span style="color: #66cc66;">&#41;</span> <span style="color: #933;">0</span> -<span style="color: #933;">200px</span> <span style="color: #993333;">no-repeat</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#panel2b</span> a<span style="color: #3333ff;">:hover</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">test<span style="color: #933;">-3</span><span style="color: #6666ff;">.jpg</span></span><span style="color: #66cc66;">&#41;</span> -<span style="color: #933;">96px</span> -<span style="color: #933;">200px</span> <span style="color: #993333;">no-repeat</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#panel3b</span> a<span style="color: #3333ff;">:hover</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">test<span style="color: #933;">-3</span><span style="color: #6666ff;">.jpg</span></span><span style="color: #66cc66;">&#41;</span> -<span style="color: #933;">172px</span> -<span style="color: #933;">200px</span> <span style="color: #993333;">no-repeat</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #cc00cc;">#panel4b</span> a<span style="color: #3333ff;">:hover</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">test<span style="color: #933;">-3</span><span style="color: #6666ff;">.jpg</span></span><span style="color: #66cc66;">&#41;</span> -<span style="color: #933;">283px</span> -<span style="color: #933;">200px</span> <span style="color: #993333;">no-repeat</span>;<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Où a-t-on trouvé ces valeurs en pixel ? On ne va pas le cacher : la première valeur est bien évidemment le décalage horizontal (en partant du bord gauche), et la deuxième le décalage vertical.</p>
<p>Toutes les valeurs verticales sont les même : étant donné que l&#8217;image principale fait 400px de haut, et que notre état &#8220;après&#8221; commence à l&#8217;exact milieu, on a simplement divisé la hauteur en deux. Décaler l&#8217;image de fond vers le haut de 200px signifie qu&#8217;on applique une valeur négative. Pensez que le haut du lien est le point de départ, ou 0. Pour positionner l&#8217;image de fond à 200px au dessus de ce point, il est sensé de bouger le point de départ de -200px.</p>
<p>De même, si le côté gauche de chaque lien correspond aussi à 0, on doit décaler l&#8217;image de fond de la largeur additionné de chaque balise <code>&lt;li&gt;</code> précédent le lien sur lequel on travaille. Donc, le premier lien ne nécessite pas de décalage, puisque qu&#8217;il n&#8217;y a pas de pixel avant son point de départ horizontal. Le deuxième lien requiert un décalage de la largeur du premier, le troisième lien requiert un décalage de la largeur combinée des deux premiers, et le dernier requiert un décalage de la largeur combinée des trois précédents liens.</p>
<p>C&#8217;est un peu lourd à expliquer comme procédé, mais le fait de jouer un peu avec ces valeurs va rapidement vous montrer comment marche le décalage, et une fois familier de son fonctionnement, vous verrez que ce n&#8217;est pas si compliqué à faire.</p>
<p>Et <a href="http://www.laumaille.net/wp-content/uploads/2007/11/image3.html">voilà</a> ! Tout vos liens en roll-over avec une seule et même image, réduite en HTML à une simple liste.</p>
<h2>Les boutons</h2>
<p>Il n&#8217;y a aucune raison pour que les liens soient collés, côte-à-côte comme dans l&#8217;exemple précédent. Une image avec des zones cliquables peut être utile dans certains cas, mais pourquoi ne pas séparer chaque lien dans son propre bouton autonome ? Ainsi, on peut ajouter des bordures et des marges à chacun, et de manière générale, les traiter aussi séparemment selon nos besoins.</p>
<p>En fait, les briques sont déjà en places. Nous n&#8217;avons pas vraiment besoin de modifier notre code de manière radicale ; le changement principal est de créer une image qui ne soit pas continue de lien en lien, comme c&#8217;était le cas dans l&#8217;exemple précédent. Puisque l&#8217;on ne peut pas compter sur la balise <code>&lt;ul&gt;</code> pour placer notre image de fond, on va l&#8217;appliquer sur chaque balise <code>&lt;li&gt;</code> en décalant de manière différente pour chaque, comme on a décalé pour l&#8217;état &#8220;après&#8221; dans l&#8217;exemple précédant.</p>
<p>Avec une <a href="http://www.laumaille.net/wp-content/uploads/2007/11/icons.gif">image appropriée</a> et un peu d&#8217;espacement entre chaque <code>&lt;li&gt;</code>, on obtient des <a href="http://www.laumaille.net/wp-content/uploads/2007/11/buttons1.html">boutons</a>.</p>
<p>Notez que dans cet exemple, on a ajouté des bordures de 1px qui, bien sûr, s&#8217;ajoutent à la largeur finale de notre lien. Cela affecte nos valeurs de décalage ; on compense ceci en ajoutant un décalage de 2px aux endroits appropriés.</p>
<h2>Les formes irrégulières</h2>
<p>Jusqu&#8217;à présent, nous nous sommes uniquement concentrés sur des formes rectangulaires, qui ne s&#8217;entrecroisent pas. Mais qu&#8217;en est il d&#8217;images cliquables plus complexes que les tronçonneurs d&#8217;image comme Fireworks ou ImageReady exportent si facilement ? Relax, on couvre ça aussi.</p>
<p>On commence de la même manière que le premier exemple, en appliquant l&#8217;image de fond sur la balise <code>&lt;ul&gt;</code>, en supprimant les puces de la liste, en fixant les tailles, etc. La grosse différence vient de la manière dont on positionne les balises <code>&lt;li&gt;</code> ; le but étant d&#8217;encadrer chaque élément avec une boite aux <a href="http://www.laumaille.net/wp-content/uploads/2007/11/blobs1.html">bordures très ajustées</a>.</p>
<p>Une fois de plus, grâce à la possibilité d&#8217;utiliser une positionnement absolu relatif au coin en haut à gauche de la balise <code>&lt;ul&gt;</code>, nous sommes capable de placer nos liens exactement où l&#8217;on veut qu&#8217;ils soient. Maintenant, tout ce qu&#8217;il nous reste à faire est de d&#8217;afficher <a href="http://www.laumaille.net/wp-content/uploads/2007/11/blobs2.html">l&#8217;état &#8220;après&#8221;</a>.</p>
<p>Malheureusement, dans ce cas, une simple image &#8220;avant/après&#8221; ne suffit pas. À cause de l&#8217;entrelacement des objets, se reposer sur un seul état &#8220;après&#8221; ferait apparaître des morceaux d&#8217;objets environnants également dans un état &#8220;après&#8221;. En fait, cela montrerait précisémment les morceaux entremêlés aux bordures du lien. (Plus facile <a href="http://www.laumaille.net/wp-content/uploads/2007/11/blobs3.html">à voir</a> qu&#8217;à lire.)</p>
<p>Comment éviter ça ? En ajoutant un deuxième état &#8220;après&#8221;, et en sélectionnant soigneusement quels objets vont où. <a href="http://www.laumaille.net/wp-content/uploads/2007/11/blobs.gif">L&#8217;image principale</a> à dans ce cas mis les objets bleu et pourpre dans le premier état &#8220;après&#8221;, et les objets vert, orange et jaune dans le second. Cet ordre permet que deux objets entrelacés et adjacents ne soient pas sur la même image &#8220;après&#8221;. Ainsi, <a href="http://www.laumaille.net/wp-content/uploads/2007/11/blobs2.html">l&#8217;illusion est complète</a>.</p>
<h2>Avantages et inconvénients</h2>
<p>Quelques remarques en guise de conclusion. Notre nouvelle méthode de Sprites CSS passe bien sur la plupart des navigateurs récents. La seule exception notable est Opera 6, qui n&#8217;applique pas l&#8217;image de fond sur le lien à l&#8217;état <code>:hover</code>. Pourquoi, ce n&#8217;est pas sûr, mais il semblerait que l&#8217;état <code>:hover</code> ne soit pas pris en compte. Les liens fonctionnent bien, et s&#8217;ils ont été correctement nommés, le résultat sera une simple image avec des zones cliquables dans Opera 6. On devrait pouvoir vivre avec, surtout depuis que Opera 7 est sorti.</p>
<p>La deuxième remarque sera familière à tout ceux qui ont déjà passé du temps avec la technique <a href="http://www.alistapart.com/articles/fir/">FIR</a>. Dans les rares cas où<br />
l&#8217;utilisateur aura désactivé les images mais gardé le CSS, un gros blanc va apparaître en lieu et place de notre image. Les liens seront toujours présent et toujours cliquables, mais il n&#8217;y aura rien de visuel. Pour l&#8217;instant, il n&#8217;y a pas de solution pour ce problème.</p>
<p>Ensuite, il y a la taille du fichier. Un fausse idée serait de penser qu&#8217;une grande image contenant les états &#8220;avant/après&#8221; sera plus lourde que plusieurs images découpées, puisque l&#8217;image sera plus grande. Mais chaque format d&#8217;image contient un entête (ce qui explique qu&#8217;un GIF blanc de 1px par 1px fasse environ 50 octets), et plus on découpe les images, plus on a d&#8217;entêtes (bah oui, 1 par image). En plus, une grande image générale ne contiendra qu&#8217;une seule palette de couleurs pour un GIF, tandis que chaque image découpée aurait la sienne. Les tests préliminaires démontrent un poid de page plus faible avec les Sprites CSS,<br />
ou au pire, un poid supérieur négligeable.</p>
<p>Enfin, n&#8217;oublions pas que notre balisage est beau et propre, avec tous les avantages que cela entraine. La liste HTML s&#8217;affiche parfaitement dans un environnement dégradé, et une technique de remplacement par l&#8217;image laissera le texte des liens accessibles aux navigateurs vocaux. Le remplacement des sprites est très simple, puisque toutes les dimensions et décalages sont gérés par un seul fuchier CSS, et que tous les Sprites sont dans une seule image.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/11/23/sprites-css-la-mort-du-decoupage-dimage/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Bonjour tout le monde !</title>
		<link>http://www.laumaille.net/2007/11/22/bonjour-tout-le-monde/</link>
		<comments>http://www.laumaille.net/2007/11/22/bonjour-tout-le-monde/#comments</comments>
		<pubDate>Thu, 22 Nov 2007 16:22:47 +0000</pubDate>
		<dc:creator>Divad</dc:creator>
		
		<category><![CDATA[Divers]]></category>

		<guid isPermaLink="false">http://www.laumaille.net/?p=1</guid>
		<description><![CDATA[Alors ce coup-ci c&#8217;est reparti pour de bon !!
Avec WordPress, je viens vraiment de trouver la solution qu&#8217;il me fallait&#8230; En plus, c&#8217;est du XHTML + CSS, donc j&#8217;adore encore plus !! A moi de faire en sorte que le thème reste valide XHTML maintenant. Mais avec les templates de FreeCSSTemplates, ça devrait pas être [...]]]></description>
			<content:encoded><![CDATA[<p>Alors ce coup-ci c&#8217;est reparti pour de bon !!</p>
<p>Avec WordPress, je viens vraiment de trouver la solution qu&#8217;il me fallait&#8230; En plus, c&#8217;est du XHTML + CSS, donc j&#8217;adore encore plus !! A moi de faire en sorte que le thème reste valide XHTML maintenant. Mais avec les templates de <a href="http://www.freecsstemplates.org/" title="FreeCSSTemplates">FreeCSSTemplates</a>, ça devrait pas être bien compliqué !</p>
<p>Et puis WordPress, c&#8217;est vraiment tip top ! Plus je l&#8217;utilise, plus je l&#8217;aime ! J&#8217;ai déjà commencé à toucher aux thèmes : j&#8217;ai rarement des trucs aussi simples ! Bon, c&#8217;est sûr, on peut le voir soit comme un gros moteur de site, soit comme un petit CMS, mais dans tous les cas, j&#8217;ai l&#8217;impression que la communauté derrière est plutôt active, et que plus WordPress avance dans le temps, plus il comporte de fonctionnalités !</p>
<p>Bon, c&#8217;est pas le tout, mais j&#8217;ai plutôt intérêt à retourner bosser moi&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.laumaille.net/2007/11/22/bonjour-tout-le-monde/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
