Flyweight
Flyweight design pattern is a way to compact large structure into smaller structure with granular shareable structures backed by a caching mechanism. This is commonly seen in GUI implementation where larger widget is broken down into smaller widget and a set of GUI libraries. It requires a factory to manage the flyweight objects.
Also, flyweight design pattern is also use in big data, where a set of data can be so large that it employs caching. This design however, requires client to be disciplined not to create the Flyweight object on his/her own but strictly via its factory generator. This is to ensure the factory is able to cache the object creation.
The diagram is as follows:
When to Use (Problem)
- Data set is large and requires break-down into smaller pieces and caching reusable parts.
Example (Solution)
Here is an example in Go:
package main
import (
"fmt"
"time"
)
// Flyweight is the object that is sharable across number of objects
// efficiently.
type Flyweight struct {
Data string
}
// FlyweightFactory is the factory that creates and caches the Flyweight objects
type FlyweightFactory struct {
pool map[string]*Flyweight
}
// NewFlyweightFactory creates the new factory object
func NewFlyweightFactory() *FlyweightFactory {
return &FlyweightFactory{
pool: make(map[string]*Flyweight),
}
}
func (f *FlyweightFactory) GetFlyweight(name string) *Flyweight {
flyweight, okay := f.pool[name]
if !okay {
flyweight = &Flyweight{
Data: name,
}
time.Sleep(5 * time.Second)
fmt.Printf("APP - taken 5 seconds to create one \n")
f.pool[name] = flyweight
}
return flyweight
}
// client
func main() {
f := NewFlyweightFactory()
o1 := f.GetFlyweight("alice")
fmt.Printf("o1 Data: %v\n", o1.Data)
o2 := f.GetFlyweight("bruce")
fmt.Printf("o2 Data: %v\n", o2.Data)
o3 := f.GetFlyweight("alice")
fmt.Printf("o3 Data: %v\n", o3.Data)
o4 := f.GetFlyweight("alice")
fmt.Printf("o4 Data: %v\n", o4.Data)
}
// Output:
// APP - taken 5 seconds to create one
// o1 Data: alice
// APP - taken 5 seconds to create one
// o2 Data: bruce
// o3 Data: alice
// o4 Data: alice
Notice that when the data structure is large that it takes 5 seconds to create one. On the first attempt to create alice
and bruce
objects, the notice where 5 seconds has taken shown up. However, the subsequent alice
objects are a lot faster thanks to the factory's flyweight caching mechanism. This way, it speeds up the object design creation at the expense of caching memory space.
Expected Outcome (Consequences)
- Object creation is faster for large data structure and data set.
- More memory is used for caching.