Hourra ! La version française est enfin sortie ! Laissez-nous un message svp, si vous voulez nous faire part de vos commentaires ou signaler une erreur.
Monteur

Monteur en C#

Le Monteur est un patron de conception de création qui permet de construire des objets complexes étape par étape.

Le monteur n’est pas comme les autres patrons de création : les produits n’ont pas besoin d’avoir une interface commune. Il est ainsi possible de créer différents produits en utilisant le même procédé de fabrication.

Utilisation du patron de conception en C#

Complexité :

Popularité :

Exemples d’utilisation : Le monteur est bien connu dans le monde du C#. Il se montre très utile lorsque vous devez créer un objet possédant de nombreuses configurations possibles.

Identification : Le monteur peut être identifié à l’intérieur d’une classe qui n’a qu’une seule méthode de création et plusieurs méthodes permettant de configurer l’objet en résultant. Les méthodes du monteur prennent souvent en charge le chaînage (par exemple, someBuilder->setValueA(1)->setValueB(2)->create()).

Exemple conceptuel

Dans cet exemple, nous allons voir la structure du patron de conception Monteur. Nous allons répondre aux questions suivantes :

  • Que contiennent les classes ?
  • Quels rôles jouent-elles ?
  • Comment les éléments du patron sont-ils reliés ?

Program.cs: Exemple conceptuel

using System;
using System.Collections.Generic;

namespace RefactoringGuru.DesignPatterns.Builder.Conceptual
{
    // The Builder interface specifies methods for creating the different parts
    // of the Product objects.
    public interface IBuilder
    {
        void BuildPartA();
		
        void BuildPartB();
		
        void BuildPartC();
    }
    
    // The Concrete Builder classes follow the Builder interface and provide
    // specific implementations of the building steps. Your program may have
    // several variations of Builders, implemented differently.
    public class ConcreteBuilder : IBuilder
    {
        private Product _product = new Product();
        
        // A fresh builder instance should contain a blank product object, which
        // is used in further assembly.
        public ConcreteBuilder()
        {
            this.Reset();
        }
        
        public void Reset()
        {
            this._product = new Product();
        }
		
        // All production steps work with the same product instance.
        public void BuildPartA()
        {
            this._product.Add("PartA1");
        }
		
        public void BuildPartB()
        {
            this._product.Add("PartB1");
        }
		
        public void BuildPartC()
        {
            this._product.Add("PartC1");
        }
		
        // Concrete Builders are supposed to provide their own methods for
        // retrieving results. That's because various types of builders may
        // create entirely different products that don't follow the same
        // interface. Therefore, such methods cannot be declared in the base
        // Builder interface (at least in a statically typed programming
        // language).
        //
        // Usually, after returning the end result to the client, a builder
        // instance is expected to be ready to start producing another product.
        // That's why it's a usual practice to call the reset method at the end
        // of the `GetProduct` method body. However, this behavior is not
        // mandatory, and you can make your builders wait for an explicit reset
        // call from the client code before disposing of the previous result.
        public Product GetProduct()
        {
            Product result = this._product;

            this.Reset();

            return result;
        }
    }
    
    // It makes sense to use the Builder pattern only when your products are
    // quite complex and require extensive configuration.
    //
    // Unlike in other creational patterns, different concrete builders can
    // produce unrelated products. In other words, results of various builders
    // may not always follow the same interface.
    public class Product
    {
        private List<object> _parts = new List<object>();
		
        public void Add(string part)
        {
            this._parts.Add(part);
        }
		
        public string ListParts()
        {
            string str = string.Empty;

            for (int i = 0; i < this._parts.Count; i++)
            {
                str += this._parts[i] + ", ";
            }

            str = str.Remove(str.Length - 2); // removing last ",c"

            return "Product parts: " + str + "\n";
        }
    }
    
    // The Director is only responsible for executing the building steps in a
    // particular sequence. It is helpful when producing products according to a
    // specific order or configuration. Strictly speaking, the Director class is
    // optional, since the client can control builders directly.
    public class Director
    {
        private IBuilder _builder;
        
        public IBuilder Builder
        {
            set { _builder = value; } 
        }
        
        // The Director can construct several product variations using the same
        // building steps.
        public void buildMinimalViableProduct()
        {
            this._builder.BuildPartA();
        }
		
        public void buildFullFeaturedProduct()
        {
            this._builder.BuildPartA();
            this._builder.BuildPartB();
            this._builder.BuildPartC();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // The client code creates a builder object, passes it to the
            // director and then initiates the construction process. The end
            // result is retrieved from the builder object.
            var director = new Director();
            var builder = new ConcreteBuilder();
            director.Builder = builder;
            
            Console.WriteLine("Standard basic product:");
            director.buildMinimalViableProduct();
            Console.WriteLine(builder.GetProduct().ListParts());

            Console.WriteLine("Standard full featured product:");
            director.buildFullFeaturedProduct();
            Console.WriteLine(builder.GetProduct().ListParts());

            // Remember, the Builder pattern can be used without a Director
            // class.
            Console.WriteLine("Custom product:");
            builder.BuildPartA();
            builder.BuildPartC();
            Console.Write(builder.GetProduct().ListParts());
        }
    }
}

Output.txt: Résultat de l’exécution

Standard basic product:
Product parts: PartA1

Standard full featured product:
Product parts: PartA1, PartB1, PartC1

Custom product:
Product parts: PartA1, PartC1

Monteur dans les autres langues

Patrons de conception : Monteur en Java Patrons de conception : Monteur en C++ Patrons de conception : Monteur en PHP Patrons de conception : Monteur en Python Patrons de conception : Monteur en Ruby Patrons de conception : Monteur en Swift Patrons de conception : Monteur en TypeScript Patrons de conception : Monteur en Go