Javascript. Flyweight pattern

Паттерн Приспособленец (Flyweight pattern) используется в случае, если один экземпляр класса может предоставлять много "виртуальных экземпляров". То есть вместо создания тысяч объектов определенного типа, можно создать один объект, который будет хранить состояние всех этих объектов. Данный паттерн нашел себя в системах с критическими требованиям к ресурсам. Паттерн относится к структурным паттернам. В общем виде uml диаграмма данного паттерна выглядит следующим образом.


Рассмотрим конкретный пример реализации.

/* Flyweight interface */

var Shape = function () {
this.draw = function () {};
}

/* ConcreteFlyweight */

var Circle = function (color) {
var color = color,
x,
y,
radius;

this.setX = function (_x) {
x = _x;
};

this.setY = function (_y) {
y = _y;
};

this.setRadius = function (_radius) {
radius = _radius;
};

this.draw = function () {
console.log("Circle: Draw() [Color: " + color +
", x: " + x + ", y: " + y + ", radius: " + radius);
};
};

Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;

/* FlyweightFactory */
var ShapeFactory = (function () {
var circleMap = {},
getCircle = function (color) {
var circle = circleMap[color] || null;
if (circle === null) {
circle = new Circle(color);
circleMap[color] = circle;
console.log("Creating circle of color: " + color);
}
return circle;
},
ShapeFactory = function () {};

ShapeFactory.getCircle = getCircle;
return ShapeFactory;
})(); 

// testing...

var Application = function () {
var colors = ["Red", "Green", "Blue", "White", "Black"],

getRandomColor = function () {
return parseInt((Math.random() * colors.length), 10);
},

getRandomX = function () {
return parseInt((Math.random() * 100), 10);
},

getRandomY = function () {
return parseInt((Math.random() * 100), 10);
};


this.run = function () {
for (var i = 0, circle; i < 20; ++i) {
circle = ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
};
};

var app = new Application();
app.run();

На выходе:

Creating circle of color: 2
Circle: Draw() [Color: 2, x: 48, y: 96, radius: 100
Creating circle of color: 0
Circle: Draw() [Color: 0, x: 45, y: 33, radius: 100
Creating circle of color: 3
Circle: Draw() [Color: 3, x: 52, y: 48, radius: 100
Circle: Draw() [Color: 3, x: 32, y: 64, radius: 100
Circle: Draw() [Color: 2, x: 70, y: 66, radius: 100
Creating circle of color: 4
Circle: Draw() [Color: 4, x: 46, y: 62, radius: 100
Circle: Draw() [Color: 2, x: 84, y: 49, radius: 100
Circle: Draw() [Color: 0, x: 57, y: 57, radius: 100
Circle: Draw() [Color: 3, x: 12, y: 39, radius: 100
Circle: Draw() [Color: 3, x: 98, y: 90, radius: 100
Circle: Draw() [Color: 2, x: 9, y: 88, radius: 100
Circle: Draw() [Color: 3, x: 2, y: 68, radius: 100
Circle: Draw() [Color: 0, x: 69, y: 74, radius: 100
Circle: Draw() [Color: 2, x: 65, y: 91, radius: 100
Circle: Draw() [Color: 2, x: 57, y: 60, radius: 100
Circle: Draw() [Color: 2, x: 72, y: 24, radius: 100
Circle: Draw() [Color: 3, x: 34, y: 23, radius: 100
Circle: Draw() [Color: 3, x: 24, y: 13, radius: 100
Circle: Draw() [Color: 4, x: 62, y: 84, radius: 100
Circle: Draw() [Color: 3, x: 81, y: 22, radius: 100