Prototype Design Pattern in C# with Examples

Prototype Design Pattern in C# with Examples

In this article, we are going to discuss prototype design patterns in C#.

prototype design patterns are the creational design pattern.

As per the Gang of Four Definition: "Prototype Design Pattern Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype"

As per the prototype design pattern, we need to create an object once and can use it across the application, creating an object again and again in an application is an expensive and time-consuming task so as per this pattern once we create an object, we can utilize it wherever we need it.

  • reducing the complexity of the application to create the objects.
  • reduce the need to creating of an object again and again.
  • We can remove the object in runtime.

Prototype Design Pattern in C# 

below is an example of creating a prototype design pattern using the shallow copy method. here we are using the inbuild ICloneable interface.

public class Student: ICloneable
{
    public string Name { get; set; }
    public string Address { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
    public object Clone()
    {
        return this.MemberwiseClone();
    }
 
}
public class ProtoTypeDesignPattern
{
    static void Main(string[] args)
    {
        Student _student = new Student
        {
            Name = "dotnetOffice",
            Address = "XYZ",
            Age = 10,
            Gender = "Male"
        };

        Console.WriteLine($"Student Name:  {_student.Name}");

        Student cloneName = _student.Clone() as Student;
        Console.WriteLine($"Cloned Name:  {_student.Name}");

        cloneName.Name = "other name";
        Console.WriteLine($"origional name - {_student.Name}");
        Console.WriteLine($"Cloned Name - {cloneName.Name}");
    }
}

 

Fluent Interface Design Pattern in C# with Examples

Fluent Interface Design Pattern in C# with Examples


In this article, we will talk about the Fluent Interface Design Pattern in C# with examples. The Fluent Interface Design Pattern is a type of Creational Design Pattern.

Fluent Interface Design Pattern

The purpose of a fluent design pattern is to use multiple properties for the objects by connecting them with the .(dot) without giving the specifics of the object again.

A fluent interface design pattern is implemented by using the method cascading or concrete method chaining.

Implementation of Fluent Interface Design Pattern in C#
let's create a student class

public class Student
{

    public string Name { get; set; }

    public int Age { get; set; }

    public string Address { get; set; }

}

now let's assign values to student class

Student emp = new Student()
{

    Name  = "DotNet office",

    Age  = 12,

    Address  = "India"

};


What is Method Chaining?

Method chaining is the technique where each method returns an object and all of these methods can be chained together to create a single statement. to implement this, first, we need to create the wrapper class around the student class.

 public class StudentFluentExample


    {

        private Student obj = new Student();

        public StudentFluentExample NameOfTheStudent(string name)

        {

          obj.Name = name;

            return;

        }

        public StudentFluentExample Age(int age)

        {

            obj.Age = age;

            return;

        }

        public StudentFluentExample LivesIn(string address)

        {

            obj.Address = address;

            return;

        }

       

    }

now to access the above class methods we have to create an object of the class like below

as per fluent interfaces design pattern, we can access properties by connecting them with .(dot) like below
static void Main(string[] args)

        {
          StudentFluentExample obj = new StudentFluentExample();
          obj.NameOfTheStudent("Dotnet office").Age(12).LivesIn("India");

        }

uses of the Fluent Interface Design Pattern in C#
  1. Fluent code is more readable and allows us to vary a product's internal representation
  2. A fluent design pattern encapsulates the code for construction and representation and it Provides control over the steps of the object construction process.
  3. Sorting, Searching, and pagination using LINQ are some of the real-world examples of the fluent interface in the combination with the builder design pattern.


Builder Design Pattern in C# with Real-time Example in C#

Builder Design Pattern in C# with Real-time Example in C#

In this article, we will discuss the Builder Design Pattern in C# with models. it is part of the Creational Design Pattern.

Definition: "Separate the construction of a complex object from its representation so that the same construction process can create different representations"

Builder Design Pattern solves the situation of increasing constructor parameters and constructors of a given class by providing a step-by-step initialization of Parameters. After step-by-step initialization, it returns the resulting constructed object at once.

 

The Builder Design Pattern is a creational design pattern that allows you to create complex objects step by step. It separates the construction of a complex object from its representation, allowing the same construction process to create different representations.

Here's a real-time example in C#: constructing a House object with various parts (walls, roof, etc.).

Step 1: Define the Product Class

public class House {

    public string Basement { get; set; }

    public string Structure { get; set; }

    public string Roof { get; set; }

    public string Interior { get; set; } 

public override string ToString()
{
    return $"House with Basement: {Basement}, Structure: {Structure}, Roof: {Roof}, Interior: {Interior}";
}
}

 

Step 2: Define the Builder Interface

public interface IHouseBuilder
{
     void BuildBasement();
     void BuildStructure();
     void BuildRoof();
     void BuildInterior();
     House GetHouse();
}

 

Step 3: Implement Concrete Builders

public class ConcreteHouseBuilder : IHouseBuilder
{
    private House _house = new House();

    public void BuildBasement()
    {
        _house.Basement = "Concrete Basement";
    }

    public void BuildStructure()
    {
        _house.Structure = "Concrete and Steel Structure";
    }

    public void BuildRoof()
    {
        _house.Roof = "Concrete Roof";
    }

    public void BuildInterior()
    {
        _house.Interior = "Painted Walls with Wooden Flooring";
    }

    public House GetHouse()
    {
        return _house;
    }
}

public class WoodenHouseBuilder : IHouseBuilder
{
    private House _house = new House();

    public void BuildBasement()
    {
        _house.Basement = "Wooden Basement";

    }

    public void BuildStructure()
    {
        _house.Structure = "Wood and Iron Structure";

    }

    public void BuildRoof()
    {
        _house.Roof = "Wooden Roof";
    }

    public void BuildInterior()
    {
        _house.Interior = "Wooden Walls with Carpet Flooring";
    }

    public House GetHouse()
    {
        return _house;
    }
}

 

Step 4: Define the Director Class

public class Director
{
    private IHouseBuilder _houseBuilder;

    public Director(IHouseBuilder houseBuilder)
    {
         _houseBuilder = houseBuilder;
    }

    public void ConstructHouse()
    {
        _houseBuilder.BuildBasement();
        _houseBuilder.BuildStructure();
        _houseBuilder.BuildRoof();
        _houseBuilder.BuildInterior();
    }

    public House GetHouse()
    {
        return _houseBuilder.GetHouse();
    }

}

 

Step 5: Use the Builder Pattern

class Program
{
    static void Main(string[] args)
    {
        IHouseBuilder concreteHouseBuilder = new ConcreteHouseBuilder();
        Director director = new Director(concreteHouseBuilder);
        director.ConstructHouse();
        House concreteHouse = director.GetHouse();
        Console.WriteLine(concreteHouse);

        IHouseBuilder woodenHouseBuilder = new WoodenHouseBuilder();
        director = new Director(woodenHouseBuilder);

        director.ConstructHouse();
        House woodenHouse = director.GetHouse();
        Console.WriteLine(woodenHouse);

    }

}

 

Explanation

  1. House: The product class, which has various parts such as Basement, Structure, Roof, and Interior.
  2. IHouseBuilder: The builder interface with methods to build different parts of the house and a method to get the final house object.
  3. ConcreteHouseBuilder and WoodenHouseBuilder: Concrete builder classes that implement the IHouseBuilder interface to build a concrete house and a wooden house, respectively.
  4. Director: The director class that constructs a house using the builder interface.
  5. Program: The client code that uses the builder pattern to create different types of houses.

This example shows how the Builder Design Pattern can be used to construct complex objects with a step-by-step approach, ensuring the same construction process can produce different representations of the object.

 

Abstract Factory Design Pattern in C# with Real-Time Example

Abstract Factory Design Pattern in C# with Real-Time Example

In this article, we will discuss Abstract Factory Design Patterns in C# with models. it is a type of Creational Design Pattern.

What is Abstract Factory Design Pattern?

According to the Gang of Four Definition: “The Abstract Factory Design Pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes “.

The Abstract Factory Design Pattern is a creational pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. It allows you to produce different sets of products that belong to different families.
The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes

Abstract Factory pattern belongs to creational patterns and is one of the most used design patterns in real-world applications

An abstract factory is a super factory that creates other factories

We need to Choose an Abstract Factory Pattern when

  1. The application needs to create multiple families of objects or products
  2. We need to use only one of the subsets of families of objects at a given point of time
  3. We want to hide the implementations of the families of products by decoupling the implementation of each of these operations

Here's a real-time example in C#: creating a family of UI components (buttons and text boxes) for different platforms (Windows and Mac).

Step 1: Define Abstract Product Interfaces


public interface IButton
{
    void Render();
}

public interface ITextBox
{
    void Render();
}

Step 2: Implement Concrete Products

public class WindowsButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Rendering Windows Button");
    }
}

public class MacButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Rendering Mac Button");
    }
}

public class WindowsTextBox : ITextBox
{
    public void Render()
    {
        Console.WriteLine("Rendering Windows TextBox");
    }
}

public class MacTextBox : ITextBox
{
    public void Render()
    {
        Console.WriteLine("Rendering Mac TextBox");
    }

}

Step 3: Define Abstract Factory Interface


public interface IUIFactory
{
    IButton CreateButton();

    ITextBox CreateTextBox();
}

Step 4: Implement Concrete Factories


public class WindowsFactory : IUIFactory
{
    public IButton CreateButton()
    {
        return new WindowsButton();
    }

    public ITextBox CreateTextBox()
    {
        return new WindowsTextBox();
    }
}

public class MacFactory : IUIFactory
{
    public IButton CreateButton()
    {
        return new MacButton();
    }

    public ITextBox CreateTextBox()
    {
        return new MacTextBox();
    }
}

Step 5: Use the Abstract Factory Pattern

class Program
{
    static void Main(string[] args)
    {
        IUIFactory factory;
        // Create a Windows UI

        factory = new WindowsFactory();

        IButton windowsButton = factory.CreateButton();

        ITextBox windowsTextBox = factory.CreateTextBox();

        windowsButton.Render();

        windowsTextBox.Render();
        // Create a Mac UI

        factory = new MacFactory();

        IButton macButton = factory.CreateButton();

        ITextBox macTextBox = factory.CreateTextBox();

        macButton.Render();

        macTextBox.Render();

    }

}

Explanation

  1. IButton and ITextBox: Abstract product interfaces that define the common behavior for buttons and text boxes.
  2. WindowsButton, MacButton, WindowsTextBox, and MacTextBox: Concrete product classes that implement the abstract product interfaces for different platforms.
  3. IUIFactory: The abstract factory interface that declares methods for creating abstract products (buttons and text boxes).
  4. WindowsFactory and MacFactory: Concrete factory classes that implement the IUIFactory interface to create products for Windows and Mac platforms, respectively.
  5. Program: The client code that uses the abstract factory pattern to create a family of related UI components for different platforms.

This example demonstrates how the Abstract Factory Design Pattern can be used to create families of related objects without specifying their concrete classes, making it easy to switch between different product families (e.g., Windows UI and Mac UI) without changing the client code.

 

When to use it Abstract Factory Design Pattern?

When we need to use the Abstract Factory Design Pattern in the following cases

  1. When you want to create a set of related objects or dependent objects which must be used together.
  2. When the system should be configured to work with multiple families of products.
  3. When the Concrete classes should be decoupled from the clients.


Differences between Abstract Factory and Factory Method Design Pattern:

Factory Method Design Pattern in C#

Factory Method Design Pattern in C#


in this article, we will discuss the Factory Method Design Pattern in C# with examples. It is a Creational Design Pattern. Previously we discussed the Factory Design Pattern which is also a part of the Creation design pattern.

What is the Factory Method Design Pattern?

As per Factory Method Design Pattern is used when we want to create the object of the class without exposing the logic of object creation to the client. 

According to the Gang of Four Definition “Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method class defer instantiation it uses to subclasses”.

to implement it in the factory method design pattern we need to create the abstract class as part of the Factory class which will create an object and return the object of the product class, and here subclasses will decide which class needs to instantiate. 

The Factory Method Design Pattern is a creational pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. This pattern helps in defining a method that will create objects, and it lets the subclasses decide which class to instantiate.

Here is a real-time example in C#: creating a logging framework where different types of loggers (e.g., Console Logger, File Logger) can be instantiated based on the configuration.

Step 1: Define the Product Interface

public interface ILogger
{
    void Log(string message);
}

Step 2: Implement Concrete Products
public class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine($"Console Logger: {message}");
    }
}

public class FileLogger : ILogger
{
    public void Log(string message)
    {
        // For demonstration purposes, we'll just simulate logging to a file
        Console.WriteLine($"File Logger: {message}");
    }
}


Step 3: Define the Creator Class
public abstract class LoggerFactory
{
    public abstract ILogger CreateLogger();

    public void LogMessage(string message)
    {
        var logger = CreateLogger();
        logger.Log(message);
    }
}


Step 4: Implement Concrete Creators
public class ConsoleLoggerFactory : LoggerFactory
{
    public override ILogger CreateLogger()
    {
        return new ConsoleLogger();
    }
}

public class FileLoggerFactory : LoggerFactory
{
    public override ILogger CreateLogger()
    {
        return new FileLogger();
    }
}

Step 5: Use the Factory Method Pattern

class Program
{
    static void Main(string[] args)
    {
        LoggerFactory loggerFactory;

        // Using Console Logger
        loggerFactory = new ConsoleLoggerFactory();
        loggerFactory.LogMessage("This is a message for the console logger.");

        // Using File Logger
        loggerFactory = new FileLoggerFactory();
        loggerFactory.LogMessage("This is a message for the file logger.");
    }
}

Explanation

  1. ILogger: The product interface that defines the Log method.
  2. ConsoleLogger and FileLogger: Concrete product classes that implement the ILogger interface.
  3. LoggerFactory: The abstract creator class that defines the factory method CreateLogger. It also provides a LogMessage method that uses the logger created by the factory method.
  4. ConsoleLoggerFactory and FileLoggerFactory: Concrete creator classes that implement the factory method to create instances of ConsoleLogger and FileLogger, respectively.
  5. Program: The client code that uses the factory method pattern to log messages using different types of loggers.

Summary

The Factory Method Design Pattern:

  • Defines an interface for creating an object, but lets subclasses alter the type of object that will be created.
  • Helps in decoupling the client code from the concrete classes it needs to instantiate.
  • Provides flexibility to introduce new types of loggers without modifying the client code.

In this example, the logging framework can be extended to support more types of loggers (e.g., Database Logger, Network Logger) by simply adding new concrete creator classes without changing the existing client code.

 

 

Factory Design Pattern in C# with Real-Time Example

Factory Design Pattern in C# with Real-Time Example

Factory Design Pattern in C#?

As per Gang of Four, the Factory Design Pattern is “Define an interface for creating an object but let sub-classes decide which class to instantiate. The Factory method class defers instantiation it uses to the sub-classes”. In the Factory pattern, we create product objects without exposing the logic to the end user.

he Factory Design Pattern is a creational pattern that provides a way to instantiate objects without exposing the creation logic to the client. Instead, the client uses a factory method to create the object. This pattern is useful when the exact type of object required cannot be predicted until runtime.

Real-Time Example: Shape Creation

Imagine a graphics application that needs to create various shapes like circles, squares, and rectangles. The exact type of shape to create might depend on user input or some other runtime condition. The Factory Design Pattern can be used to handle this.

Step 1: Define the Product Interface

public interface IShape
{
    void Draw();
}

Step 2: Implement Concrete Products

public class Circle : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Circle");
    }
}

public class Square : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Square");
    }
}

public class Rectangle : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Rectangle");
    }
}

Step 3: Define the Factory Class

public static class ShapeFactory
{
    public static IShape GetShape(string shapeType)
    {
        switch (shapeType.ToLower())
        {
            case "circle":
                return new Circle();
            case "square":
                return new Square();
            case "rectangle":
                return new Rectangle();
            default:
                throw new ArgumentException("Invalid shape type");
        }
    }
}

Step 4: Use the Factory Pattern

class Program
{
    static void Main(string[] args)
    {
        IShape shape1 = ShapeFactory.GetShape("circle");
        shape1.Draw();

        IShape shape2 = ShapeFactory.GetShape("square");
        shape2.Draw();

        IShape shape3 = ShapeFactory.GetShape("rectangle");
        shape3.Draw();
    }
}

Explanation

  1. IShape: The product interface that defines the Draw method.
  2. Circle, Square, and Rectangle: Concrete product classes that implement the IShape interface.
  3. ShapeFactory: The factory class with a GetShape method that takes a shape type as an argument and returns an instance of the corresponding shape. The factory uses a switch statement to decide which shape to create.
  4. Program: The client code that uses the factory pattern to create different shapes and calls their Draw method.

Summary

The Factory Design Pattern:

  • Provides a way to instantiate objects without exposing the creation logic.
  • Helps in creating objects where the exact type may not be known until runtime.
  • Encapsulates the object creation logic in a single place, making it easier to manage and extend.

In this example, the ShapeFactory class encapsulates the logic for creating different shapes. The client code simply calls the GetShape method with the desired shape type, and the factory takes care of creating the correct shape instance. This makes it easy to add new shapes to the application without modifying the existing client code.

 Difference B/w Factory and Factory Method design pattern

👉👉👉👉👉 Factory Method design pattern

The terms "Factory" and "Factory Method" both refer to creational design patterns in object-oriented programming, but they have distinct purposes and implementations. Here's a detailed explanation of the differences between the Factory Pattern and the Factory Method Pattern:

Factory Pattern

Also known as the "Simple Factory" pattern, this is a design pattern where a separate class (the factory) is responsible for creating instances of different classes based on provided input.

Characteristics

  1. Static Methods: The Factory typically uses static methods to create objects.
  2. Single Responsibility: Centralizes object creation logic in one place, making it easier to manage and modify.
  3. Not a GoF Pattern: The Factory Pattern is not one of the original "Gang of Four" (GoF) design patterns but is still widely used.

Example

 public interface IShape

{
    void Draw();
}

public class Circle : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Circle");
    }
}

public class Square : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Square");
    }
}

public class ShapeFactory
{
    public static IShape GetShape(string shapeType)
    {
        switch (shapeType.ToLower())
        {
            case "circle":
                return new Circle();
            case "square":
                return new Square();
            default:
                throw new ArgumentException("Invalid shape type");
        }
    }
}

// Usage
class Program
{
    static void Main(string[] args)
    {
        IShape shape1 = ShapeFactory.GetShape("circle");
        shape1.Draw();

        IShape shape2 = ShapeFactory.GetShape("square");
        shape2.Draw();
    }
}


Factory Method Pattern

The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. The Factory Method Pattern lets a class defer instantiation to subclasses.

Characteristics

  1. Inheritance: Relies on inheritance, where a base class defines the factory method, and derived classes implement this method.
  2. More Flexible: Allows subclasses to alter the type of objects that will be created.
  3. GoF Pattern: It is one of the original "Gang of Four" design patterns.

Example


public interface IShape
{
    void Draw();
}

public class Circle : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Circle");
    }
}

public class Square : IShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Square");
    }
}

public abstract class ShapeFactory
{
    public abstract IShape CreateShape();

    public void DrawShape()
    {
        IShape shape = CreateShape();
        shape.Draw();
    }
}

public class CircleFactory : ShapeFactory
{
    public override IShape CreateShape()
    {
        return new Circle();
    }
}

public class SquareFactory : ShapeFactory
{
    public override IShape CreateShape()
    {
        return new Square();
    }
}

// Usage
class Program
{
    static void Main(string[] args)
    {
        ShapeFactory factory1 = new CircleFactory();
        factory1.DrawShape();

        ShapeFactory factory2 = new SquareFactory();
        factory2.DrawShape();
    }
}

 

Key Differences

  • Intent:
    • Factory Pattern: Centralizes object creation logic in a single method or class.
    • Factory Method Pattern: Uses inheritance to allow subclasses to decide which class to instantiate.
  • Implementation:
    • Factory Pattern: Typically uses static methods and does not rely on inheritance.
    • Factory Method Pattern: Uses abstract or virtual methods that subclasses override to create specific instances.
  • Flexibility:
    • Factory Pattern: Less flexible as it centralizes creation logic.
    • Factory Method Pattern: More flexible as it allows subclasses to customize the creation process.
  • Design Complexity:
    • Factory Pattern: Simpler to implement and understand.
    • Factory Method Pattern: More complex, but offers greater extensibility.

When to Use

  • Factory Pattern: When you have a straightforward object creation process that can be centralized and doesn't need to be extended or customized.
  • Factory Method Pattern: When you anticipate that the object creation process will need to be extended or customized by subclasses.

Each pattern has its own strengths and use cases, and the choice between them depends on the specific needs of your application.