-
Notifications
You must be signed in to change notification settings - Fork 3
Flyweight Pattern
Pablo Garcia edited this page Jul 22, 2017
·
11 revisions
The Flyweight pattern is a classical structural solution for optimizing code that is repetitive, slow and inefficiently shares data. It aims to minimize the use of memory in an application by sharing as much data as possible with related objects (e.g application configuration, state and so on).
flyweights
(type: Object) Key-value pair list with the objects added.
create(name, creator, ...args)
Creates new instances based on a heuristic.
-
name
(type: String) Alias of the new object to be created. -
creator
(type: Object or Function) Value of the new object, if it is a function it will be executed with the arguments passed. -
args
(type: Anything) Arguments that only matter if the `creator is a function. These will be passed as arguments.
heuristic(name)
Returns true to create a new instance.
-
name
(type: String) Alias of the new object to be created.
The most basic implementation, of all the patterns, do not require any options.
var patterns = require('go-patterns');
var Flyweight = patterns.flyweight().build();
var flyweight = new Flyweight();
var someObject = flyweight.create('someObject', { test: 'testing' });
var sameObject = flyweight.create('someObject', { test: 'should not overwrite previous object' });
console.log(flyweight.flyweights['someObject'].test); // => testing
console.log(flyweight.flyweights['someObject'] === someObject); // => true
console.log(flyweight.flyweights['someObject'] === sameObject); // => true
This little example shows memoization with a factorial algorithm using flyweight.
var patterns = require('go-patterns');
var FactorialMemoizationFlyweight = patterns.flyweight({
constructor: function() {
// shadowing
this.create = this.create.bind(this);
},
publics: {
create(val) {
return this.flyweights[`${val}`] = this.flyweights[`${val}`] || this.factorial(val);
},
factorial(val) {
if(val <= 1) return 1;
return val * this.factorial(val - 1);
}
}
}).build();
factorialMemoizationFlyweight = new FactorialMemoizationFlyweight();
[2, 3, 4, 4].forEach(factorialMemoizationFlyweight.create);
console.log(factorialMemoizationFlyweight.flyweights); // => { '2': 2, '3': 6, '4': 24 }
var patterns = require('go-patterns');
function HeavyObjectInitialization(value) {
this.data = value;
this.store = [];
for(var i = 0; i < value; i++) {
this.store.push((i + 1) * Math.random());
}
}
var LightObjectCreation = patterns.flyweight({
constructor: function() {
// this overrides the default object.
this.flyweights = [];
},
publics: {
heuristic(params) {
return this.find(params) || this.construct(params);
},
construct(params) {
var heavyObject = new HeavyObjectInitialization(params.data);
this.flyweights.push(heavyObject);
return heavyObject;
},
find(params) {
for(var i = 0, l = this.flyweights.length; i < l; i++) {
if(this.flyweights[i].data === params.data) {
return this.flyweights[i];
}
}
return null;
}
}
}).build();
var lightObjectCreation = new LightObjectCreation();
lightObjectCreation.create({
data: 2 // dummy specific data
});
lightObjectCreation.create({
data: 2 // dummy specific data
});
console.log(lightObjectCreation.flyweights); // => [ HeavyObjectInitialization { data: 2, store: [ 0.39935513992626603, 1.7727831649111456 ] } ]