Prototype pattern clones an existing object to create a new object, instead of building a new object at runtime. This helps reduce resource usage, as the complex object creation/initiation process is replaced with cloning existing objects. This is very useful for keeping object cached and/or default object.
NOTES
In this article, we discuss the implementation of the Prototype Pattern in Go.
See the Prototype in other languages in the “Other Code Implementations” section. Or, use the link below to check the details of the Prototype Pattern-
Implementation
Here are the key points of Prototype pattern implementation in go –
- Define an interface and declare a cloning method (usually called “Clone”).
- Define the item structs, for the actual objects.
- Define “Clone” method for the struct, as part of “Prototype” interface implementation. In the method, create new item object, assign values and then return that.
- While using the implementation- call the “Clone” method of the item object, and that will return a new object created using the prototype pattern. Cast the result as the item struct type, if needed.
Simple implementation of Prototype pattern in GoLang-
package main
import "fmt"
// Define an interface for prototype
type Prototype interface {
// Declare Clone method which has return type of the same interface type "Prototype"
Clone() Prototype
}
// Define struct
type SampleStruct1 struct {
Prop1, Prop2 int
}
func NewSampleStruct1() (sampleStruct1 *SampleStruct1) {
sampleStruct1 = &SampleStruct1{}
return
}
// Define "Clone" method as part of "Prototype" implementation
func (sampleStruct1 *SampleStruct1) Clone() Prototype {
cloneObj := NewSampleStruct1()
cloneObj.Prop1 = sampleStruct1.Prop1
cloneObj.Prop2 = sampleStruct1.Prop2
return cloneObj
}
// Demo
func main() {
// Create an original object
originalObj := NewSampleStruct1()
originalObj.Prop1 = 11
originalObj.Prop2 = 99
fmt.Println(originalObj)
// Call the "Clone" method
// also cast the result the original struct
cloneOfOriginalObj := originalObj.Clone().(*SampleStruct1)
cloneOfOriginalObj.Prop1 = 1001
fmt.Println(cloneOfOriginalObj)
}
This will generate following output-
&{11 99}
&{1001 99}
Examples
Here are a few examples of Prototype pattern implementation and usage.
Example #1: Transport
Here we are demonstrating prototype implementation for different vehicles, like Car, Plane etc.
Prototype Interface
- Create file “prototype.go”.
- Define interface “Prototype”.
- Declare the method “Clone” and set the return type as of type “Prototype”.
// prototype.go
package main
type Prototype interface {
Clone() Prototype
}
Car Struct
- Create file “car.go”.
- Define item struct “Car”.
- Define method “NewCar” for the struct. Create a new “Car” object and return it in the method.
- Define method “Clone” for the struct, as part of “Prototype” interface implementation. In the method, create a new “Car” object, set the values from the existing object, and then return it.
// car.go
package main
import "fmt"
type Car struct {
Make int
Model string
Color string
}
func NewCar() (car *Car) {
car = &Car{}
return
}
func (car *Car) Clone() Prototype {
carClone := NewCar()
carClone.Make = car.Make
carClone.Model = car.Model
carClone.Color = car.Color
return carClone
}
func (car *Car) ToString() string {
return fmt.Sprintf("Make: %v | Model: %v | Color: %v", car.Make, car.Model, car.Color)
}
Plane Struct
- Create file “plane.go”.
- Define item struct “Plane”.
- Define method “NewPlane” for the struct. Create a new “Plane” object and return it in the method.
- Define method “Clone” for the struct. Create a new “Car” object, in the “Clone” method, then set the values and return it.
// plane.go
package main
import "fmt"
type Plane struct {
Model string
Color string
}
func NewPlane() (plane *Plane) {
plane = &Plane{}
return
}
func (plane *Plane) Clone() Prototype {
planeClone := NewPlane()
planeClone.Model = plane.Model
planeClone.Color = plane.Color
return planeClone
}
func (plane *Plane) ToString() string {
return fmt.Sprintf("Model: %v | Color: %v", plane.Model, plane.Color)
}
Demo
- Create file “main.go”.
- Create a “Car” object and set values. Here we have saved it in “car1” variable.
- Then call the “Clone” method on the original object “car1”.
- The clone method return type will be of “Prototype” interface. We need to cast the result as “Car”, that’s why we have used “car1.Clone().(*Car)” to cast the interface type as the struct type “(*Car)”.
// main.go
package main
import "fmt"
func main() {
car1 := NewCar()
car1.Make = 2014
car1.Model = "ABCD"
car1.Color = "Red"
fmt.Println(car1.ToString())
carClone := car1.Clone().(*Car)
carClone.Model = "Some Different Model"
carClone.Color = "White"
fmt.Println(carClone.ToString())
}
Output
We will get the following output-
Make: 2014 | Model: ABCD | Color: Red
Make: 2014 | Model: Some Different Model | Color: White
Source Code
Use the following link to get the source code:
Example | Source Code Link |
---|---|
Example #1: Transport | GitHub |
Other Code Implementations
Use the following links to check Prototype pattern implementation in other programming languages.