Creational Design Patterns in C#, JavaScript, Dart, and GoLang

Creational design patterns play a crucial role in software development as they provide flexible object creation mechanisms. They encapsulate the logic of creating objects, making it easier to manage object creation and improve code maintainability. In this article, we will explore some commonly used creational patterns in C#, JavaScript, Dart, and GoLang.

Singleton Pattern

The Singleton pattern ensures that there is only one instance of a class throughout the application. This can be useful when you need to have a single point of access to a resource or when creating a shared object. Here’s an example of implementing the Singleton pattern in C#:

public class Singleton
{
    private static Singleton instance;

    private Singleton()
    {
        // Private constructor to prevent external instantiation
    }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

Factory Method Pattern

The Factory Method pattern provides an interface for creating objects, but allows subclasses to determine the actual class to instantiate. This decouples the client code from the specific classes being created. Here’s an example of using the Factory Method pattern in JavaScript:

class Car {
    constructor(make, model) {
        this.make = make;
        this.model = model;
    }
}

class CarFactory {
    createCar(make, model) {
        return new Car(make, model);
    }
}

const factory = new CarFactory();
const car = factory.createCar("Toyota", "Camry");

Abstract Factory Pattern

The Abstract Factory pattern provides an interface for creating families of related objects. It allows the client code to create objects without specifying their concrete classes. Here’s an example of implementing the Abstract Factory pattern in Dart:

abstract class Button {
  void display();
}

class MaterialButton implements Button {
  void display() {
    print("Material Button");
  }
}

class CupertinoButton implements Button {
  void display() {
    print("Cupertino Button");
  }
}

abstract class GUIFactory {
  Button createButton();
}

class MaterialFactory implements GUIFactory {
  Button createButton() {
    return MaterialButton();
  }
}

class CupertinoFactory implements GUIFactory {
  Button createButton() {
    return CupertinoButton();
  }
}

class Application {
  Button button;

  Application(GUIFactory factory) {
    button = factory.createButton();
  }

  void createUI() {
    button.display();
  }
}

final factory = CupertinoFactory();
final application = Application(factory);
application.createUI();

Builder Pattern

The Builder pattern separates the creation of an object from its representation, allowing the same construction process to create different representations. It provides a step-by-step approach to building complex objects. Here’s an example of using the Builder pattern in GoLang:

type Car struct {
    Make  string
    Model string
    Color string
}

type CarBuilder struct {
    car Car
}

func (b *CarBuilder) SetMake(make string) *CarBuilder {
    b.car.Make = make
    return b
}

func (b *CarBuilder) SetModel(model string) *CarBuilder {
    b.car.Model = model
    return b
}

func (b *CarBuilder) SetColor(color string) *CarBuilder {
    b.car.Color = color
    return b
}

func (b *CarBuilder) Build() Car {
    return b.car
}

func main() {
    car := CarBuilder{}.
        SetMake("Toyota").
        SetModel("Camry").
        SetColor("Blue").
        Build()
}

These are just a few examples of creational patterns commonly used in C#, JavaScript, Dart, and GoLang. By leveraging these patterns, you can enhance the flexibility and maintainability of your codebase. Make sure to understand the specific requirements of your application before choosing the appropriate creational pattern to implement.