DEV Community

varma36a
varma36a

Posted on • Updated on

Design Pattens

Solution to common problems

  1. Creational
  2. Structural
  3. Behavioural

DRY - Dont repeat yourself

Singleton

Usecases

  1. Database Connections
    • In java it uses Executor to manage threads through thread pool
    • we use singleton to manage single connection
  2. Logging
- when we append logs we need only one instance, because if you dont manage it via singleton we will be having multiple files and also consistency issues
Enter fullscreen mode Exit fullscreen mode
  1. Configuration files
    • performance issue, depending on the size of the file
    • inconsistency

--If your class doesnt have any state then we go for static
-- if you have non static one instance of the class will have one value and other instance of the class will have one value

-- if you make constructor in singleton private or protected(depending on your requirement), you will not allow others to create instance of this class
-- global access point

The telescoping constructor anti-pattern occurs when a class has multiple constructors with different combinations of parameters, leading to a proliferation of constructors. This can make the code difficult to maintain and understand. An alternative is to use the builder pattern.

Example without telescoping constructor anti-pattern:

public class Car {
    private String brand;
    private String model;
    private int year;
    private String color;

    public Car(String brand, String model, int year, String color) {
        this.brand = brand;
        this.model = model;
        this.year = year;
        this.color = color;
    }
}
Telescoping constructor anti-pattern example:


public class Car {
    private String brand;
    private String model;
    private int year;
    private String color;

    public Car(String brand) {
        this.brand = brand;
    }

    public Car(String brand, String model) {
        this(brand);
        this.model = model;
    }

    public Car(String brand, String model, int year) {
        this(brand, model);
        this.year = year;
    }

    public Car(String brand, String model, int year, String color) {
        this(brand, model, year);
        this.color = color;
    }
}
Enter fullscreen mode Exit fullscreen mode

This pattern becomes unwieldy as the number of parameters increases, making it hard to read and maintain. The builder pattern provides a more flexible solution by allowing the client code to set parameters selectively.

Builder

  1. Telescoping Constructor: Telescoping constructor is a term used to describe a class that has multiple constructors, where each constructor calls another constructor in the chain. The term "telescoping" comes from the idea that the constructors are nested inside each other like the sections of a collapsible telescope.

Here's an example in C#:



public class Example
{
    public string Property1 { get; }
    public int Property2 { get; }
    public bool Property3 { get; }

    // Constructor with the minimum required parameters
    public Example(string property1, int property2)
        : this(property1, property2, false)
    {
    }

    // Constructor with additional parameters
    public Example(string property1, int property2, bool property3)
    {
        Property1 = property1;
        Property2 = property2;
        Property3 = property3;
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the second constructor calls the first constructor using : this(property1, property2, false) and provides a default value for the third parameter. This pattern continues if more parameters are added.

  1. Builder Design Pattern: The Builder design pattern is used to construct a complex object step by step. It involves a director class that orchestrates the construction by using a builder interface. The builder interface defines the steps to build the object, and concrete builder classes implement these steps. The client uses the director to construct the object using a specific builder.

The Builder pattern helps avoid the telescoping constructor anti-pattern by providing a more readable and maintainable way to construct complex objects.

Here's a simplified example in C#:


public class Product
{
    public string Property1 { get; }
    public int Property2 { get; }
    public bool Property3 { get; }

    public Product(string property1, int property2, bool property3)
    {
        Property1 = property1;
        Property2 = property2;
        Property3 = property3;
    }
}

public interface IBuilder
{
    IBuilder SetProperty1(string value);
    IBuilder SetProperty2(int value);
    IBuilder SetProperty3(bool value);
    Product Build();
}

public class ConcreteBuilder : IBuilder
{
    private string property1;
    private int property2;
    private bool property3;

    public IBuilder SetProperty1(string value)
    {
        property1 = value;
        return this;
    }

    public IBuilder SetProperty2(int value)
    {
        property2 = value;
        return this;
    }

    public IBuilder SetProperty3(bool value)
    {
        property3 = value;
        return this;
    }

    public Product Build()
    {
        return new Product(property1, property2, property3);
    }
}

public class Director
{
    public Product ConstructProduct(IBuilder builder)
    {
        return builder
            .SetProperty1("Value1")
            .SetProperty2(42)
            .SetProperty3(true)
            .Build();
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the Director class uses the ConcreteBuilder to construct a Product object step by step. This pattern is more flexible and easier to maintain than adding more and more parameters to constructors, especially when dealing with optional or default values.

This is used to make object creation through a seperate Class.

use case: whenever we have complex object initialization logic

we can either do it

  1. Property
  2. Constructor

If we do it via property somebody can mutate the object

  • we want the object to be immutable, constructor is the way to initialize and make it immutable

  • We can also do validations just before initializing

Prototype

Usecase: Whenever we want to create lot of object, and also if the object creation is expensive

UseCase:

  1. Game Development

Top comments (0)