<?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, s