In this post, we will learn how to use and implement the Flyweight Pattern in Golang with an example.
Flyweight is used to manage the state of an object with high variation. The pattern allows us to share common parts of the object state among multiple objects, instead of each object storing it. Variable object data is referred to as an extrinsic state, and the rest of the object state is intrinsic. Extrinsic data is passed to flyweight methods and will never be stored within it.
The flyweight pattern helps reduce the overall memory usage and the object initializing overhead. The pattern helps create interclass relationships and lower memory to a manageable level.
Flyweight Pattern Class Diagram
The participants of the flyweight pattern are the FlyWeight interface, ConcreteFlyWeight, FlyWeightFactory, and the Client classes:
- The FlyWeight interface has a method through which flyweights can get and act on the extrinsic state.
- ConcreteFlyWeight implements the FlyWeight interface to representflyweight objects.
- FlyweightFactory is used to create and manage flyweight objects. The client invokes FlyweightFactory to get a flyweight object. UnsharedFlyWeight can have a functionality that is not shared.
- Client classes
Golang Flyweight Pattern Implementation
Let's say DataTransferObject is an interface with the getId() method. DataTransferObjectFactory creates a data transfer object through getDataTransferObject() by the DTO type. The DTO types are customer, employee,manager, and address.
Let's create a file named "flyweight.go" and add the following source code to it:
package main
// importing fmt package
import (
"fmt"
)
//DataTransferObjectFactory struct
type DataTransferObjectFactory struct {
pool map[string]DataTransferObject
}
//DataTransferObjectFactory class method getDataTransferObject
func (factory DataTransferObjectFactory) getDataTransferObject(dtoType string) DataTransferObject {
var dto = factory.pool[dtoType]
if dto == nil {
fmt.Println("new DTO of dtoType: " + dtoType)
switch dtoType {
case "customer":
factory.pool[dtoType] = Customer{id: "1"}
case "employee":
factory.pool[dtoType] = Employee{id: "2"}
case "manager":
factory.pool[dtoType] = Manager{id: "3"}
case "address":
factory.pool[dtoType] = Address{id: "4"}
}
dto = factory.pool[dtoType]
}
return dto
}
// DataTransferObject interface
type DataTransferObject interface {
getId() string
}
//Customer struct
type Customer struct {
id string //sequence generator
name string
ssn string
}
// Customer class method getId
func (customer Customer) getId() string {
//fmt.Println("getting customer Id")
return customer.id
}
//Employee struct
type Employee struct {
id string
name string
}
//Employee class method getId
func (employee Employee) getId() string {
return employee.id
}
//Manager struct
type Manager struct {
id string
name string
dept string
}
//Manager class method getId
func (manager Manager) getId() string {
return manager.id
}
//Address struct
type Address struct {
id string
streetLine1 string
streetLine2 string
state string
city string
}
//Address class method getId
func (address Address) getId() string {
return address.id
}
//main method
func main() {
var factory = DataTransferObjectFactory{make(map[string]DataTransferObject)}
var customer DataTransferObject = factory.getDataTransferObject("customer")
fmt.Println("Customer ", customer.getId())
var employee DataTransferObject = factory.getDataTransferObject("employee")
fmt.Println("Employee ", employee.getId())
var manager DataTransferObject = factory.getDataTransferObject("manager")
fmt.Println("Manager", manager.getId())
var address DataTransferObject = factory.getDataTransferObject("address")
fmt.Println("Address", address.getId())
}
Output:
G:\GoLang\examples>go run flyweight.go new DTO of dtoType: customer Customer 1 new DTO of dtoType: employee Employee 2 new DTO of dtoType: manager Manager 3 new DTO of dtoType: address Address 4
Comments
Post a Comment