Skip to content

Commit

Permalink
chore(annexe): Builder - lien externe pour exemple théorique (refs #24)
Browse files Browse the repository at this point in the history
  • Loading branch information
mborne committed Dec 11, 2023
1 parent 8c51c5e commit b1c8fc6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 215 deletions.
120 changes: 24 additions & 96 deletions docs/annexe/design_pattern/creational/Builder.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Les patrons de conception (Annexes) - Builder</title>
<title>Les patrons de conception (Annexes) - Builder (Monteur)</title>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css"
integrity="sha512-b2QcS5SsA8tZodcDtGRELiGv5SaKSk1vDHDaQRda0htPYWZ6046lr3kJ5bAAQdpV2mmA/4v0wQF9MyU6/pDIAg=="
Expand Down Expand Up @@ -58,104 +58,32 @@
<a href="https://github.com/mborne/cours-patron-conception/blob/master/src/annexe/design_pattern/creational/Builder.md?plain=1" target="_blank">Éditer sur GitHub</a>
</div>
<div class="markdown-body">
<h1 id="builder">Builder</h1><h2 id="problème">Problème</h2><p>Les fabriques traitent principalement de l&#39;instanciation de classes en présence d&#39;une hiérarchie.</p>
<p>Le patron de conception &quot;Builder&quot; s&#39;attaque à l&#39;instanciation de classes où
la complexité est liée à la complexité des objets et relations entre ces objets.</p>
<p>En outre, ce patron de conception est utile quand :</p>
<h1 id="builder-monteur">Builder (Monteur)</h1><h2 id="problème">Problème</h2><p>Les fabriques traitent principalement de l&#39;instanciation de classes en présence d&#39;une hiérarchie.</p>
<p>Le patron de conception &quot;Builder&quot; s&#39;attaque à l&#39;instanciation de classes où la complexité est liée à la complexité des objets et relations entre ces objets.</p>
<p>En outre, ce patron de conception sera utile pour <strong>éviter</strong> :</p>
<ul>
<li>On est tenté par la multiplication des constructeurs</li>
<li>On doit appeler de nombreux accesseurs (set, add, etc.)</li>
</ul>
<h2 id="solution">Solution</h2><ul>
<li>On met en place un nombre minimum de constructeurs</li>
<li>On délègue la complexité de création des instances à des objets dédiés : Director et Builder</li>
<li>De <strong>nombreux appels à des accesseurs</strong> (set, add, etc.)</li>
<li>La <strong>multiplication des constructeurs</strong></li>
</ul>
<h2 id="solution">Solution</h2><p>Dans sa forme originale, le patron de conception monteur préconise de déléguer la complexité de la construction à des instances dédiée (Builder et Director) comme suit :</p>
<p><img src="uml/UML_DP_Builder.png" alt="UML Builder"></p>
<p>Source <a href="https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Builder" target="_blank">https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Builder</a></p>
<h2 id="exemple">Exemple</h2><p>Source : <a href="https://fr.wikipedia.org/wiki/Monteur_%28patron_de_conception%29#Java" target="_blank">https://fr.wikipedia.org/wiki/Monteur_%28patron_de_conception%29#Java</a></p>
<h3 id="un-produit-pizza">Un produit Pizza</h3><pre><code class="language-java">/* Produit */
class Pizza {
private String pate = &quot;&quot;;
private String sauce = &quot;&quot;;
private String garniture = &quot;&quot;;

public void setPate(String pate){
this.pate = pate;
}

public void setSauce(String sauce){
this.sauce = sauce;
}
public void setGarniture(String garniture) {
this.garniture = garniture;
}
}
</code></pre>
<h3 id="un-monteur-abstrait-de-pizza">Un monteur abstrait de pizza</h3><pre><code class="language-java">/* Monteur */
abstract class MonteurPizza {
protected Pizza pizza;

public Pizza getPizza() { return pizza; }
public void creerNouvellePizza() { pizza = new Pizza(); }

public abstract void monterPate();
public abstract void monterSauce();
public abstract void monterGarniture();
}
</code></pre>
<h3 id="des-monteurs-concrets">Des monteurs concrets</h3><ul>
<li>Monteur pizza hawaii</li>
</ul>
<pre><code class="language-java">class MonteurPizzaHawaii extends MonteurPizza {
public void monterPate() { pizza.setPate(&quot;croisée&quot;); }
public void monterSauce() { pizza.setSauce(&quot;douce&quot;); }
public void monterGarniture() { pizza.setGarniture(&quot;jambon+ananas&quot;); }
}
</code></pre>
<p>Un <a href="https://fr.wikipedia.org/wiki/Monteur_%28patron_de_conception%29#Java" target="_blank">exemple en Java est disponible</a> avec :</p>
<ul>
<li>Monteur pizza piquante</li>
<li>Des <strong>Pizza</strong> (<em>Product</em>) </li>
<li>Une interface <strong>MonteurPizza</strong> (<em>Builder</em>) avec deux implémentations (<em>ConcreteBuilder</em>)<ul>
<li><strong>MonteurPizzaReine</strong></li>
<li><strong>MonteurPizzaPiquante</strong></li>
</ul>
<pre><code class="language-java">class MonteurPizzaPiquante extends MonteurPizza {
public void monterPate() { pizza.setPate(&quot;feuilletée&quot;); }
public void monterSauce() { pizza.setSauce(&quot;piquante&quot;); }
public void monterGarniture() { pizza.setGarniture(&quot;pepperoni+salami&quot;); }
}
</code></pre>
<h3 id="un-serveur-dans-le-rôle-du-directeur">Un serveur dans le rôle du Directeur</h3><pre><code class="language-java">class Serveur {
private MonteurPizza monteurPizza;

public void setMonteurPizza(MonteurPizza mp) {
monteurPizza = mp;
}

public Pizza getPizza() {
return monteurPizza.getPizza();
}

public void construirePizza() {
monteurPizza.creerNouvellePizza();
monteurPizza.monterPate();
monteurPizza.monterSauce();
monteurPizza.monterGarniture();
}
}
</code></pre>
<h3 id="exemple-dutilisation">Exemple d&#39;utilisation</h3><pre><code class="language-java">Serveur serveur = new Serveur();
MonteurPizza monteurPizzaHawaii = new MonteurPizzaHawaii();
MonteurPizza monteurPizzaPiquante = new MonteurPizzaPiquante();

serveur.setMonteurPizza(monteurPizzaHawaii);
serveur.construirePizza();

Pizza pizza = serveur.getPizza();
</code></pre>
<h2 id="variantes">Variantes</h2><p>La terminologie builder est généralisée à toute création par partie d&#39;objet via la séquence suivante :</p>
</li>
<li>Un <strong>Serveur</strong> (<em>Director</em>)</li>
</ul>
<h2 id="variantes">Variantes</h2><p>En pratique, la distinction ne sera pas toujours faite entre &quot;Director&quot; et &quot;Builder&quot;. La <strong>terminologie builder est généralisée à la création incrémentale d&#39;objet</strong> :</p>
<ul>
<li>Récupération d&#39;un builder</li>
<li>Création ou récupération d&#39;un builder</li>
<li>Définition de la cible par appels successifs au builder (add, set, etc...)</li>
<li>Récupération de l&#39;instance produite (getProduct)</li>
</ul>
<p>En outre, la distinction n&#39;est pas toujours faite entre &quot;Director&quot; et &quot;Builder&quot;.</p>
<h2 id="exemple-en-java">Exemple en Java</h2><ul>
<li><p><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html" target="_blank">StringBuilder</a></p>
</li>
Expand All @@ -169,7 +97,7 @@ <h2 id="exemple-en-java">Exemple en Java</h2><ul>
;
</code></pre>
<ul>
<li><code>ProcessBuilder</code></li>
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html" target="_blank">ProcessBuilder</a></li>
</ul>
<pre><code class="language-java">// Création du builder (argument obligatoire du processus)
ProcessBuilder pb = new ProcessBuilder(&quot;myCommand&quot;, &quot;myArg1&quot;, &quot;myArg2&quot;);
Expand All @@ -184,13 +112,13 @@ <h2 id="exemple-en-java">Exemple en Java</h2><ul>
// Récupération du processus
Process p = pb.start();
</code></pre>
<ul>
<li><a href="https://locationtech.github.io/jts/javadoc/org/locationtech/jts/triangulate/DelaunayTriangulationBuilder.html" target="_blank">locationtech.github.io - JTS - DelaunayTriangulationBuilder</a></li>
</ul>
<h2 id="liens-utiles">Liens utiles</h2><ul>
<li><p><a href="https://kodelog.wordpress.com/tag/telescopic-constructor-pattern/" target="_blank">Discussion sur l&#39;intérêt des beans couplés au design pattern Builder</a></p>
</li>
<li><p><a href="http://symfony.com/doc/current/book/forms.html#building-the-form" target="_blank">Exemple d&#39;utilisation dans la création de formulaire dans Symfony (PHP)</a></p>
</li>
<li><p><a href="http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/query-builder.html#high-level-api-methods" target="_blank">Exemple d&#39;utilisation dans la création de requête SQL (PHP)</a></p>
</li>
<li><a href="https://kodelog.wordpress.com/tag/telescopic-constructor-pattern/" target="_blank">Discussion sur l&#39;intérêt des beans couplés au design pattern Builder</a></li>
<li><a href="http://symfony.com/doc/current/book/forms.html#building-the-form" target="_blank">Exemple d&#39;utilisation dans la création de formulaire dans Symfony (PHP)</a></li>
<li><a href="http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/query-builder.html#high-level-api-methods" target="_blank">Exemple d&#39;utilisation dans la création de requête SQL (PHP)</a></li>
</ul>

</div>
Expand Down
137 changes: 18 additions & 119 deletions src/annexe/design_pattern/creational/Builder.md
Original file line number Diff line number Diff line change
@@ -1,142 +1,40 @@
# Builder
# Builder (Monteur)

## Problème

Les fabriques traitent principalement de l'instanciation de classes en présence d'une hiérarchie.

Le patron de conception "Builder" s'attaque à l'instanciation de classes où
la complexité est liée à la complexité des objets et relations entre ces objets.
Le patron de conception "Builder" s'attaque à l'instanciation de classes où la complexité est liée à la complexité des objets et relations entre ces objets.

En outre, ce patron de conception est utile quand :

* On est tenté par la multiplication des constructeurs
* On doit appeler de nombreux accesseurs (set, add, etc.)
En outre, ce patron de conception sera utile pour **éviter** :

* De **nombreux appels à des accesseurs** (set, add, etc.)
* La **multiplication des constructeurs**

## Solution

* On met en place un nombre minimum de constructeurs
* On délègue la complexité de création des instances à des objets dédiés : Director et Builder

Dans sa forme originale, le patron de conception monteur préconise de déléguer la complexité de la construction à des instances dédiée (Builder et Director) comme suit :

![UML Builder](uml/UML_DP_Builder.png)

Source [https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Builder](https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Builder)

Un [exemple en Java est disponible](https://fr.wikipedia.org/wiki/Monteur_%28patron_de_conception%29#Java) avec :


## Exemple

Source : [https://fr.wikipedia.org/wiki/Monteur_%28patron_de_conception%29#Java](https://fr.wikipedia.org/wiki/Monteur_%28patron_de_conception%29#Java)


### Un produit Pizza

```java
/* Produit */
class Pizza {
private String pate = "";
private String sauce = "";
private String garniture = "";

public void setPate(String pate){
this.pate = pate;
}

public void setSauce(String sauce){
this.sauce = sauce;
}
public void setGarniture(String garniture) {
this.garniture = garniture;
}
}
```

### Un monteur abstrait de pizza

```java
/* Monteur */
abstract class MonteurPizza {
protected Pizza pizza;

public Pizza getPizza() { return pizza; }
public void creerNouvellePizza() { pizza = new Pizza(); }

public abstract void monterPate();
public abstract void monterSauce();
public abstract void monterGarniture();
}
```

### Des monteurs concrets

* Monteur pizza hawaii

```java
class MonteurPizzaHawaii extends MonteurPizza {
public void monterPate() { pizza.setPate("croisée"); }
public void monterSauce() { pizza.setSauce("douce"); }
public void monterGarniture() { pizza.setGarniture("jambon+ananas"); }
}
```

* Monteur pizza piquante

```java
class MonteurPizzaPiquante extends MonteurPizza {
public void monterPate() { pizza.setPate("feuilletée"); }
public void monterSauce() { pizza.setSauce("piquante"); }
public void monterGarniture() { pizza.setGarniture("pepperoni+salami"); }
}
```

### Un serveur dans le rôle du Directeur

```java
class Serveur {
private MonteurPizza monteurPizza;

public void setMonteurPizza(MonteurPizza mp) {
monteurPizza = mp;
}

public Pizza getPizza() {
return monteurPizza.getPizza();
}

public void construirePizza() {
monteurPizza.creerNouvellePizza();
monteurPizza.monterPate();
monteurPizza.monterSauce();
monteurPizza.monterGarniture();
}
}
```

### Exemple d'utilisation

```java
Serveur serveur = new Serveur();
MonteurPizza monteurPizzaHawaii = new MonteurPizzaHawaii();
MonteurPizza monteurPizzaPiquante = new MonteurPizzaPiquante();

serveur.setMonteurPizza(monteurPizzaHawaii);
serveur.construirePizza();

Pizza pizza = serveur.getPizza();
```
* Des **Pizza** (*Product*)
* Une interface **MonteurPizza** (*Builder*) avec deux implémentations (*ConcreteBuilder*)
* **MonteurPizzaReine**
* **MonteurPizzaPiquante**
* Un **Serveur** (*Director*)

## Variantes

La terminologie builder est généralisée à toute création par partie d'objet via la séquence suivante :
En pratique, la distinction ne sera pas toujours faite entre "Director" et "Builder". La **terminologie builder est généralisée à la création incrémentale d'objet** :

* Récupération d'un builder
* Création ou récupération d'un builder
* Définition de la cible par appels successifs au builder (add, set, etc...)
* Récupération de l'instance produite (getProduct)

En outre, la distinction n'est pas toujours faite entre "Director" et "Builder".


## Exemple en Java

* [StringBuilder](https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)
Expand All @@ -151,7 +49,7 @@ Calendar cal = new Calendar.Builder()
;
```

* `ProcessBuilder`
* [ProcessBuilder](https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html)

```java
// Création du builder (argument obligatoire du processus)
Expand All @@ -168,10 +66,11 @@ pb.directory(new File("myDir"));
Process p = pb.start();
```

* [locationtech.github.io - JTS - DelaunayTriangulationBuilder](https://locationtech.github.io/jts/javadoc/org/locationtech/jts/triangulate/DelaunayTriangulationBuilder.html)


## Liens utiles

* [Discussion sur l'intérêt des beans couplés au design pattern Builder](https://kodelog.wordpress.com/tag/telescopic-constructor-pattern/)

* [Exemple d'utilisation dans la création de formulaire dans Symfony (PHP)](http://symfony.com/doc/current/book/forms.html#building-the-form)

* [Exemple d'utilisation dans la création de requête SQL (PHP)](http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/query-builder.html#high-level-api-methods)

0 comments on commit b1c8fc6

Please sign in to comment.