Implementing the Builder pattern in C#
Before studying this topic, it is recommended that you familiarize yourself with the following topic:
Contents
- 1. The structure of the Builder pattern
- 2. Implementation of Builder pattern in C#. Example
- 3. An example of using the Builder pattern to generate arrays of random number.
- Related topics
Search other websites:
1. The structure of the Builder pattern
In the most general case, the structure of the Builder pattern is shown in Figure 1.
Figure 1. The structure of Builder pattern
⇑
2. Implementation of Builder pattern in C#. Example
2.1. Block diagram of the problem solution
The example demonstrates the implementation of the Builder pattern in C#, the structure of which is shown in Figure 2.
Figure 2. Builder pattern. Building the product of 3 parts
The following classes are declared:
- Product – a class that is a product (the result of a pattern). This is an arbitrary class. For demonstration purposes, this class declares three integer variables, each of which is conventionally considered part of the product;
- Builder is an abstract class that serves as the interface between the Director and the class that creates a concrete object (ConcreteBuilder);
- ConcreteBuilder – a class that builds a concrete object;
- Director is a class that is a manager. This class builds (configures) an object of the ConcreteBuilder class for use by the client.
- Program is a class that acts as a client. This class implements the main() function, which demonstrates the client’s work. The client contacts the Director to build an object of the ConcreteBuilder class. The constructed object is then returned to the client in the GetResult() method.
⇑
2.2. Program in C#
The text of the program in the C# programming language is as follows
using System; namespace ConsoleApp8 { // Builder pattern. An example implementation in C# // 1. A class serving as a product. Contains three parts class Product { // Internal variables private int part1, part2, part3; // Constructor public Product() { part1 = 0; part2 = 0; part3 = 0; } // Access methods public int GetPart1() { return part1; } public int GetPart2() { return part2; } public int GetPart3() { return part3; } public void SetPart1(int part1) { this.part1 = part1; } public void SetPart2(int part2) { this.part2 = part2; } public void SetPart3(int part3) { this.part3 = part3; } } // 2. A class that serves as an interface between a director and a specific builder abstract class Builder { // Method that creates the product public abstract void CreateProduct(); // Methods that build parts of a product public abstract void BuildPart1(int part); public abstract void BuildPart2(int part); public abstract void BuildPart3(int part); // Method that returns the product to the client public abstract Product GetProduct(); } // The class is a concrete builder, inherits the abstract class Builder class ConcreteBuilder : Builder { // Internal variable - reference to product private Product currentBuilder; // Methods that are declared in the abstract Builder class, they need to be implemented public override void CreateProduct() { currentBuilder = new Product(); } public override void BuildPart1(int part) { currentBuilder.SetPart1(part); } public override void BuildPart2(int part) { currentBuilder.SetPart2(part); } public override void BuildPart3(int part) { currentBuilder.SetPart3(part); } public override Product GetProduct() { return currentBuilder; } } // Class-manager, contains methods for constructing the Product object from parts class Director { // Reference to Builder private Builder builder; // Constructor - initialized by a Builder instance public Director(Builder _builder) { builder = _builder; } // A method that builds an object of the Product class from parts public void Construct() { // Construct an instance of the Product class builder.CreateProduct(); builder.BuildPart1(10); builder.BuildPart2(20); builder.BuildPart3(30); } } // Class containing the client function class Program { static void Main(string[] args) { // This is a client // 1. Declare a reference to the product Product product; // 2. Create a specific builder Builder B = new ConcreteBuilder(); // 3. Create a manager and configure it with a builder Director D = new Director(B); // 4. Call methods of building a product - entrust it to the manager D.Construct(); // 5. Return the built product to the client product = B.GetProduct(); // 6. Check how the product is built Console.WriteLine("product.part1 = {0}", product.GetPart1()); Console.WriteLine("product.part2 = {0}", product.GetPart2()); Console.WriteLine("product.part3 = {0}", product.GetPart3()); } } }
⇑
2.3. The result of the program
product.part1 = 10 product.part2 = 20 product.part3 = 30
⇑
3. An example of using the Builder pattern to generate arrays of random numbers
3.1. Task
Using the means of the C# language and the capabilities of the Builder pattern, develop a program for generating objects that are arrays of random numbers. Arrays of random numbers are represented by the following classes:
- ArrayRandomInt – an array of integers. A range is specified for this array;
- ArrayRandomChar – an array of random characters from ‘A’ to ‘Z’.
⇑
3.2. Figure, reflecting the block diagram of the task solution
Figure 3 shows the structure of the Builder pattern, which reflects the solution to this problem.
Figure 3. Builder pattern. Generating objects – arrays of random numbers
As you can see from the figure, the manager class can use the two builder classes BuildRandomInt and BuildRandomChar.
⇑
3.3. Solution. C# program. Console Application
The text of the program with the solution to the problem is as follows.
using System; namespace ConsoleApp9 { // 1. Classes that are products // 1.1. ArrayRandomInt - an array of random numbers class ArrayRandomInt { // Declare internal variable - array instance private int[] A; // Class constructor with three parameters public ArrayRandomInt(int count, int min, int max) { // Create an instance of the Random class Random rndNum = new Random(); // Construct an array of random numbers A = new int[count]; for (int i = 0; i < count; i++) { A[i] = rndNum.Next(min, max + 1); } } // Method that returns an array public int[] GetArrayInt() { return A; } } // 1.2. Array of characters from 'A' to 'Z' class ArrayRandomChar { // Array of random characters from 'A' to 'Z' private char[] A; public ArrayRandomChar(int count) { // Create an instance of Random class Random rndChar = new Random(); // Build array A A = new char[count]; int t; for (int i = 0; i < count; i++) { // Get a random character from 'A' to 'Z' A[i] = (char)(rndChar.Next((int)('Z' - 'A' + 1)) + (int)'A'); } } // Method that returns an array public char[] GetArrayChar() { return A; } } // 2. A class that serves as an interface with a client to generate an object of type int class Builder { // The class declares the methods provided to the manager class virtual public void BuildArrayInt(int count, int min, int max) { } virtual public void BuildArrayChar(int count) { } // Methods that return specific objects to the client virtual public ArrayRandomInt GetResultInt() { return null; } virtual public ArrayRandomChar GetResultChar() { return null; } } // 3. Classes - builders of ArrayRandomInt and ArrayRandomChar instances class BuildRandomInt : Builder { private ArrayRandomInt A; override public void BuildArrayInt(int count, int min, int max) { // Construct an instance of the ArrayRandomInt class A = new ArrayRandomInt(count, min, max); } override public ArrayRandomInt GetResultInt() { return A; } } class BuildRandomChar : Builder { private ArrayRandomChar A; public override void BuildArrayChar(int count) { A = new ArrayRandomChar(count); } public override ArrayRandomChar GetResultChar() { return A; } } // 4. Class, acting manager class Director { private Builder builder; // Class constructor public Director(Builder _builder) { builder = _builder; } // Method that builds an array of random numbers public void ConstructInt() { // Construct an array of 10 integers ranging from 5 to 15 builder.BuildArrayInt(10, 5, 15); } public void ConstructChar() { // Construct an array of 15 characters of type char builder.BuildArrayChar(15); } } // Client class class Program { static void Main(string[] args) { // This is a client // 1. Generating an ArrayRandomInt object // 1.1. Declare a product ArrayRandomInt AI; // This is the result - an array object of integers // 1.2. Declare a builder class Builder BI = new BuildRandomInt(); // 1.3. Declare a manager and configure it with a specific builder Director D = new Director(BI); D.ConstructInt(); // Construct an object-array of integers // 1.4. Pass array to client AI = BI.GetResultInt(); // 1.5. Return the result int[] arrInt = AI.GetArrayInt(); Console.WriteLine("Array AI:"); for (int i = 0; i < arrInt.Length; i++) Console.Write("{0} ", arrInt[i]); Console.WriteLine(); // ----------------------------------------- // 2. Generating an ArrayRandomChar object // 2.1. Declare a product ArrayRandomChar AC; // 2.2. Declare a class-builder BuildRandomChar BC = new BuildRandomChar(); // 2.3. Declare a manager class and configure it a builder Director DC = new Director(BC); // 2.4. Construct an array of char values DC.ConstructChar(); // 2.5. Pass array to client AC = BC.GetResultChar(); // 2.6. Print the resulting array for verification char[] arrChar = AC.GetArrayChar(); Console.WriteLine("Array AC:"); for (int i = 0; i < arrChar.Length; i++) Console.Write("{0} ", arrChar[i]); Console.WriteLine(); } } }
⇑
3.4. Explanation of the program
As you can see from Figure 3, the program uses two builder classes BuildRandomInt and BuildRandomChar containing two methods for constructing class objects:
- method BuildArrayInt() – creates an instance of the ArrayRandomInt class ;
- method BuildArrayChar() – creates an instance of the ArrayRandomChar class.
The ArrayRandomInt and ArrayRandomChar classes are products that are passed to the client.
The Director class is the manager class. This class implements two methods ConstructInt() and ConstructChar(), from which the BuildArrayInt() and BuildArrayChar() methods are called with specific parameters (array length, range of values).
The Builder class serves as the interface between the Director manager class and the builder classes BuildRandomInt and BuildRandomChar.
Another variant of the task implementation was possible, in which the Builder class was divided into two subclasses, for example, BuilderInt and BuilderChar.
⇑
3.5. The result of the program
After running for execution, the program will give the following result
Array AI: 5 10 14 7 5 11 10 8 9 14 Array AC: J M G N M S C H N L S Y E L V
⇑
Related topics
- Builder pattern. Review and research. Implementation in C++
- Builder pattern. Implementation in Java. Examples
⇑