Creational design patterns

In this blog, we delve into creational design patterns, focusing on the Factory Method and Singleton patterns. We provide detailed explanations and examples to help understand these concepts.

GraphQL has a role beyond API Query Language- being the backbone of application Integration
background Coditation

Creational design patterns

In our last blog, we went through design patterns and their benefits, including one of the types; structural design patterns.
In this blog, we will look into Creational design patterns and It’s Usage

Creational Design Patterns

The creational design patterns deal with the creation and initialization of objects. These patterns provide methods for creating objects in a situation-appropriate manner without specifying the exact class of object that will be created. 

These are some types of creational design patterns.

  • Factory Method
  • Abstract Factory 
  • Builder
  • Prototype

Let us discuss the Factory and Singletone pattern.

Factory Pattern

The Factory Design Pattern involves creating various objects without specifying the exact class of the object being created. In some cases, creating an object may involve intricate processes that are not suitable to be included in the client object. The factory class acts as an abstraction, hiding the complex creation logic from the client and offering a standard interface for the client to access newly created objects. The Factory Method is implemented in subclasses, which are responsible for creating the objects of the class.

Consider the following example. Suppose you have a vehicle manufacturing company, and you’re currently manufacturing Sedans and SUVs. After some time, you wanted to start manufacturing trucks, so three classes could be initialized with the common method. `CreateVehicle’ according to the parameter passed to this function will return the respective object.

  • Let us create a struct with some required data and an interface that has the CreateVechicle method

//Vehicle struct with required data
type Vehicle struct {
	Name     string
	Type     string
	MaxSpeed int32
	Engine   string
}

//Interface for factory with CreateVehicle method
type IVehicle interface {
	CreateVehicle() Vehicle
}

  • Now as per the pattern let’s implement all of these types individually with the CreateVehicle method 

func (s SUV) CreateVehicle() Vehicle {
	return Vehicle{
		Name:     "SUV Model 1",
		Type:     "SUV",
		MaxSpeed: 150,
		Engine:   "2600cc",
	}

}

//Truck Implementation
type Truck struct {
	Vehicle
}

func (t Truck) CreateVehicle() Vehicle {
	return Vehicle{
		Name:     "Truck Model 1",
		Type:     "Truck",
		MaxSpeed: 100,
		Engine:   "5000cc",
}

}

//Sedan Implementation
type Sedan struct {
	Vehicle
}

func (s Sedan) CreateVehicle() Vehicle {
	return Vehicle{
		Name:     "Sedan Model 1",
		Type:     "Sedan",
		MaxSpeed: 150,
		Engine:   "2000cc",
	}

}

  • And finally, let us implement the factory function which will give the object according to the vehicle type provide and the main method to test out implementation.

// fn to get a object for specific type of vehicle
func getVehicle(vehicleType string) (IVehicle, error) {
	if vehicleType == "Sedan" {
		return Sedan{}, nil
	}
	if vehicleType == "SUV" {
		return SUV{}, nil
	}
	if vehicleType == "Truck" {
		return Truck{}, nil
	}
	return nil, fmt.Errorf("Wrong vehicle type passed")
}

func main() {
vehicle, _ := getVehicle("Sedan")

	fmt.Printf("%+v\n", vehicle.CreateVehicle())

	vehicle, _ = getVehicle("SUV")

	fmt.Printf("%+v\n", vehicle.CreateVehicle())

	vehicle, _ = getVehicle("Truck")

	fmt.Printf("%+v\n", vehicle.CreateVehicle())
}


Singleton Pattern

The singleton pattern ensures you have one instance of an object. This is useful when only one object is required to control the action during execution. Since only one instance of the class is created, any instance fields of a Singleton are guaranteed to be unique across all instances in the system.

To implement this we will require to use the sync package provided by Go, which will ensure that the object instantiates only once.


type Object struct{}

// Initializing global object instance and sync.Once which helps us to execute the function only once
var (
	object *Object
	once   sync.Once
)

And now we will write a function that will instantiate the object.


// CreateNewObject will be called many times but will give the only object which instantiated first.
func CreateNewObject() *Object {
	if object == nil {
		once.Do(func() {
			object = &Object{}
		})
	}
	return object
}

// Calling CreateNewObject five times to ensure the same memory address is printing on each call
func main() {
	for i := 0; i < 5; i++ {
		fmt.Printf("%p\n", CreateNewObject())
	}
}

The output will be the address of the object with the same memory address.

Hello, I am Akshay Navale, a highly driven and passionate software developer, avid learner, and tech enthusiast, always striving to do better. My passion for technology drives me to continuously learn and improve.

Want to receive update about our upcoming podcast?

Thanks for joining our newsletter.
Oops! Something went wrong.

Latest Articles

Implementing Custom Instrumentation for Application Performance Monitoring (APM) Using OpenTelemetry

Application Performance Monitoring (APM) has become crucial for businesses to ensure optimal software performance and user experience. As applications grow more complex and distributed, the need for comprehensive monitoring solutions has never been greater. OpenTelemetry has emerged as a powerful, vendor-neutral framework for instrumenting, generating, collecting, and exporting telemetry data. This article explores how to implement custom instrumentation using OpenTelemetry for effective APM.

Mobile Engineering
time
5
 min read

Implementing Custom Evaluation Metrics in LangChain for Measuring AI Agent Performance

As AI and language models continue to advance at breakneck speed, the need to accurately gauge AI agent performance has never been more critical. LangChain, a go-to framework for building language model applications, comes equipped with its own set of evaluation tools. However, these off-the-shelf solutions often fall short when dealing with the intricacies of specialized AI applications. This article dives into the world of custom evaluation metrics in LangChain, showing you how to craft bespoke measures that truly capture the essence of your AI agent's performance.

AI/ML
time
5
 min read

Enhancing Quality Control with AI: Smarter Defect Detection in Manufacturing

In today's competitive manufacturing landscape, quality control is paramount. Traditional methods often struggle to maintain optimal standards. However, the integration of Artificial Intelligence (AI) is revolutionizing this domain. This article delves into the transformative impact of AI on quality control in manufacturing, highlighting specific use cases and their underlying architectures.

AI/ML
time
5
 min read