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.
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.
//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
}
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",
}
}
// 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
)
Continue here