Le modèle de conception de constructeur est un modèle de conception créative que nous pouvons utiliser pour créer un objet étape par étape. Il est assez courant d’utiliser ce modèle lors de la création d’un objet complexe. Avec ce modèle, nous pouvons créer différentes parties d’un objet étape par étape, puis connecter toutes les parties ensemble.

Sans ce modèle, nous pouvons avoir un grand constructeur qui fournit tous les paramètres nécessaires pour construire notre objet. Cela pourrait entraîner un code assez illisible et non maintenable. De plus, un constructeur avec de nombreux paramètres présente un inconvénient. Nous n’avons pas toujours besoin d’utiliser tous les paramètres.

Dans cet article, nous allons vous montrer comment implémenter le modèle de générateur pour éviter de tels constructeurs complexes. Nous allons aller plus loin et expliquer que Génériques récursifs du constructeur Modèle de conception et Constructeur à facettes Concevez des échantillons également dans nos prochains articles.

Vous pouvez télécharger le code source ici: Code source du modèle de conception du constructeur

La page principale de cette série se trouve à l’adresse Modèle de conception C #.

Cet article comprend les sections suivantes:

Mettre en œuvre le modèle de conception du constructeur

Nous allons écrire un exemple simple de création d’un rapport d’inventaire pour tous les produits de notre magasin.

Commençons donc par une simplification Product Classer:

public class Product
{
    public string Name { get; set; }
    public double Price { get; set; }
}

Nous n’utiliserons cette classe que pour stocker des données de base sur un seul produit.

Notre objet de rapport d’inventaire comprendra les parties d’en-tête, de corps et de pied de page. Il est donc tout à fait logique de diviser le processus de construction d’objet en ces trois actions. Commençons par le premier ProductStockReport Classer:

public class ProductStockReport
{
    public string HeaderPart { get; set; }
    public string BodyPart { get; set; }
    public string FooterPart { get; set; }

    public override string ToString() =>
        new StringBuilder()
        .AppendLine(HeaderPart)
        .AppendLine(BodyPart)
        .AppendLine(FooterPart)
        .ToString();
}

C’est l’objet que nous allons créer en utilisant le modèle de conception du constructeur.

Pour continuer, nous avons besoin d’une interface de constructeur pour organiser le processus de construction:

public interface IProductStockReportBuilder
{
    void BuildHeader();
    void BuildBody();
    void BuildFooter();
    ProductStockReport GetReport();
}

Nous pouvons voir que la classe de générateur concret qui va implémenter cette interface doit créer toutes les pièces pour notre objet de rapport d’inventaire et renvoyer cet objet également. Alors implémentons notre classe de constructeur concret:

public class ProductStockReportBuilder : IProductStockReportBuilder
{
    private ProductStockReport _productStockReport;
    private IEnumerable<Product> _products;

    public ProductStockReportBuilder(IEnumerable<Product> products)
    {
        _products = products;
        _productStockReport = new ProductStockReport();
    }

    public void BuildHeader()
    {
        _productStockReport.HeaderPart = $"STOCK REPORT FOR ALL THE PRODUCTS ON DATE: {DateTime.Now}n";
    }

    public void BuildBody()
    {
        _productStockReport.BodyPart = string.Join(Environment.NewLine, _products.Select(p => $"Product name: {p.Name}, product price: {p.Price}"));
    }

    public void BuildFooter()
    {
        _productStockReport.FooterPart = "nReport provided by the IT_PRODUCTS company.";
    }

    public ProductStockReport GetReport()
    {
        var productStockReport = _productStockReport;
        Clear();
        return productStockReport;
    }

    private void Clear() => _productStockReport = new ProductStockReport();
}

Cette logique est assez simple. Nous obtenons tous les produits dont nous avons besoin pour notre rapport et les instancions _productStockReport Objet. Ensuite, nous créons toutes les parties de notre objet et finalement nous le rendons. En faisant GetReport Méthode nous réinitialisons notre objet et préparons une nouvelle instance pour être prêt à générer un autre rapport. C’est un comportement normal, mais pas obligatoire.

Une fois notre logique de construction terminée, nous pouvons créer notre objet dans une classe client, ou même encapsuler le processus de création de la classe client dans une classe directeur. C’est exactement ce que nous allons faire:

public class ProductStockReportDirector
{
    private readonly IProductStockReportBuilder _productStockReportBuilder;

    public ProductStockReportDirector(IProductStockReportBuilder productStockReportBuilder)
    {
        _productStockReportBuilder = productStockReportBuilder;
    }

    public void BuildStockReport()
    {
        _productStockReportBuilder.BuildHeader();
        _productStockReportBuilder.BuildBody();
        _productStockReportBuilder.BuildFooter();
    }
}

Créer l’objet StockReport

Après avoir terminé tout ce travail, nous pouvons commencer à créer notre objet:

class Program
{
    static void Main(string[] args)
    {
        var products = new List<Product>
        {
            new Product { Name = "Monitor", Price = 200.50 },
            new Product { Name = "Mouse", Price = 20.41 },
            new Product { Name = "Keyboard", Price = 30.15}
        };

        var builder = new ProductStockReportBuilder(products);
        var director = new ProductStockReportDirector(builder);
        director.BuildStockReport();

        var report = builder.GetReport();
        Console.WriteLine(report);
    }
}

Le résultat :

Modèle de conception du constructeur - Résultat

Excellent. Nous avons créé notre objet en utilisant le modèle de conception Builder.

Constructeur courant

Fluent Builder est une petite variation du modèle de conception Builder que nous pouvons utiliser pour enchaîner nos appels Builder vers différentes actions. Pour implémenter Fluent Builder, nous devons d’abord changer l’interface Builder:

public interface IProductStockReportBuilder
{
    IProductStockReportBuilder BuildHeader();
    IProductStockReportBuilder BuildBody();
    IProductStockReportBuilder BuildFooter();
    ProductStockReport GetReport();
}

Nous devons changer la mise en œuvre de cela ProductStockReportBuilder Classe aussi:

public IProductStockReportBuilder BuildHeader()
{
    _productStockReport.HeaderPart = $"STOCK REPORT FOR ALL THE PRODUCTS ON DATE: {DateTime.Now}n";
    return this;
}

public IProductStockReportBuilder BuildBody()
{
    _productStockReport.BodyPart = string.Join(Environment.NewLine, _products.Select(p => $"Product name: {p.Name}, product price: {p.Price}"));
    return this;
}

public IProductStockReportBuilder BuildFooter()
{
    _productStockReport.FooterPart = "nReport provided by the IT_PRODUCTS company.";
    return this;
}

En raison de ces changements, nous pouvons enchaîner les appels dans le Director Classer:

public void BuildStockReport()
{
    _productStockReportBuilder
        .BuildHeader()
        .BuildBody()
        .BuildFooter();
}

Si nous démarrons notre application maintenant, le résultat sera le même, mais cette fois, nous utiliserons l’interface fluide.

Conclusion

Dans cet article, nous avons appris à créer un modèle de conception de générateur et à l’implémenter dans notre projet pour créer des objets complexes. De plus, nous avons élargi notre exemple pour inclure l’utilisation de l’interface Fluent, avec laquelle nous pouvons enchaîner nos appels de générateur.

Dans le prochain article, nous allons apprendre à mettre en œuvre Interface de création fluide avec des génériques récursifs.



Source link

Recent Posts