close up photo of programming of codes

codecungnhau.com

Một trang web về kỹ thuật lập trình

C# Design Patterns: Builder

Builder là một mẫu thiết kế khởi tạo, cho phép xây dựng các đối tượng phức tạp theo từng bước.

Không giống như các mẫu khởi tạo khác, Builder không yêu cầu các sản phẩm phải có giao diện chung. Điều đó làm cho nó có thể tạo các sản phẩm khác nhau bằng cách sử dụng cùng một quy trình xây dựng.

Sử dụng mẫu trong C#

Sử dụng: Mẫu Builder là một mẫu nổi tiếng trong C#. Nó đặc biệt hữu ích khi bạn cần tạo một đối tượng với nhiều tùy chọn cấu hình khả thi.

Nhận biết: Mẫu Builder có thể được nhận dạng trong một lớp, lớp này có một phương thức tạo duy nhất và một số phương thức để cấu hình đối tượng kết quả. Các phương thức Builder thường hỗ trợ chuỗi (ví dụ: someBuilder.setValueA(1).setValueB(2).create()).

Chương trình minh họa

Ví dụ này minh họa cấu trúc của mẫu thiết kế Builder. Nó tập trung vào việc trả lời những câu hỏi sau:

  • Nó bao gồm những lớp nào?
  • Các lớp này có vai trò gì?
  • Các thành phần của mẫu có liên quan với nhau theo cách nào?

Program.cs

using System;
using System.Collections.Generic;
namespace DesignPatterns.Builder.Conceptual
{
    // Giao diện Builder chỉ định các phương thức để tạo các phần khác nhau
    // của đối tượng sản phẩm.
    public interface IBuilder
    {
        void BuildPartA();
        
        void BuildPartB();
        
        void BuildPartC();
    }
    
    // Các lớp Concrete Builder tuân theo giao diện Builder và cung cấp các triển khai 
    // cụ thể của các bước xây dựng. Chương trình của bạn có thể có một số biến
    // thể của Builder, được triển khai khác nhau.
    public class ConcreteBuilder : IBuilder
    {
        private Product _product = new Product();
        
        // Một thể hiện builder mới phải chứa một đối tượng sản phẩm trống, được 
        // sử dụng trong quá trình lắp ráp tiếp theo.
        public ConcreteBuilder()
        {
            this.Reset();
        }
        
        public void Reset()
        {
            this._product = new Product();
        }
        
        // Tất cả các bước sản xuất đều hoạt động với cùng một thể hiện sản phẩm.
        public void BuildPartA()
        {
            this._product.Add("PartA1");
        }
        
        public void BuildPartB()
        {
            this._product.Add("PartB1");
        }
        
        public void BuildPartC()
        {
            this._product.Add("PartC1");
        }
        
        // Các Concrete Builder phải cung cấp các phương pháp của riêng họ để lấy kết
        // quả. Đó là bởi vì nhiều kiểu builder khác nhau có thể tạo ra các sản phẩm
        // hoàn toàn khác nhau không tuân theo cùng một giao diện. Do đó, các phương 
        // thức như vậy không thể được khai báo trong giao diện Builder cơ sở.
       
        // Thông thường, sau khi trả lại kết quả cuối cùng cho client, một builder dự
        // kiến sẽ sẵn sàng để bắt đầu tạo một sản phẩm khác. Đó là lý do tại sao
        // thường gọi phương thức reset ở cuối thân phương thức getProduct. Tuy
        // nhiên, việc này là không bắt buộc và bạn có thể để các builder đợi lệnh
        // gọi reset tường minh từ client trước khi loại bỏ kết quả trước đó.
        public Product GetProduct()
        {
            Product result = this._product;
            this.Reset();
            return result;
        }
    }
    
    // Chỉ nên sử dụng mẫu Builder khi sản phẩm của bạn khá phức tạp
    // và yêu cầu cấu hình có thể mở rộng.
   
    // Không giống như trong các mẫu khởi tạo khác, các builder khác nhau có thể tạo
    // ra các sản phẩm không liên quan. Nói cách khác, kết quả của các builder khác
    // nhau có thể không phải lúc nào cũng tuân theo cùng một giao diện.
    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";
        }
    }
    
    // Director chỉ chịu trách nhiệm thực hiện các bước xây dựng theo một trình tự
    // cụ thể. Nó rất hữu ích khi sản xuất sản phẩm theo trật tự hoặc cấu hình cụ
    // thể. Nói một cách chính xác, lớp Director là tùy chọn, vì client có thể kiểm
    // soát trực tiếp các builder.
    public class Director
    {
        private IBuilder _builder;
        
        public IBuilder Builder
        {
            set { _builder = value; } 
        }
        
        // Director có thể xây dựng một số biến thể sản phẩm bằng các
        // bước xây dựng giống nhau.
        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)
        {
            // Client tạo một đối tượng builder, chuyển nó cho director và sau 
            // đó bắt đầu quá trình xây dựng. Kết quả cuối cùng được truy
            // xuất từ đối tượng builder.
            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());
            // Hãy nhớ rằng, mẫu Builder có thể được sử dụng mà không có
            // lớp Director.
            Console.WriteLine("Custom product:");
            builder.BuildPartA();
            builder.BuildPartC();
            Console.Write(builder.GetProduct().ListParts());
        }
    }
}

Kết quả:

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

Đã đăng vào

trong

,

bởi

Thẻ:

Bình luận

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *