Skip to content

Commit 389b81b

Browse files
author
Tomas Corral
committed
Add Flyweight pattern
1 parent aa91c9f commit 389b81b

File tree

6 files changed

+169
-0
lines changed

6 files changed

+169
-0
lines changed

Flyweight/index.html

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<html>
2+
<head>
3+
<link type="text/css" rel="stylesheet" href="../statics/css/style.css"/>
4+
<title>FlyWeight</title>
5+
</head>
6+
<body>
7+
<div id="source">
8+
<h2>Source</h2>
9+
<pre>
10+
const CANVAS_SIZE = 600;
11+
const TREES_TO_DRAW = 99900;
12+
const TREE_TYPES = 2;
13+
const forest = new Forest();
14+
15+
const getAmountOfTreesToRender = (amount, types) => {
16+
return Math.floor(amount / types);
17+
};
18+
19+
const random = (min, max) => {
20+
return min + (Math.random() * ((max - min) + 1));
21+
}
22+
const renderForest = (forest, canvas) => {
23+
for(let i = 0; i < getAmountOfTreesToRender(TREES_TO_DRAW, TREE_TYPES); i++) {
24+
forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE), 'Red Maple', 'red', 'Red Maple texture');
25+
forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE), 'Gray Birch', 'gray', 'Gray Birch texture stub');
26+
}
27+
28+
forest.render(canvas);
29+
30+
console.log(TREES_TO_DRAW + ' trees rendered');
31+
console.log('Memory usage:');
32+
console.log('Tree size (8 bytes) * ' + TREES_TO_DRAW + '+ TreeTypes size (~30 bytes) * ' + TREE_TYPES);
33+
console.log('Total: ' + ((TREES_TO_DRAW * 8 + TREE_TYPES * 30) / 1024 / 1024) + 'MB (instead of ' + ((TREES_TO_DRAW * 38) / 1024 / 1024) + 'MB)');
34+
}
35+
36+
renderForest(new Forest(), document.createElement('canvas'));
37+
</pre>
38+
</div>
39+
<div id="console">
40+
<h2>Console</h2>
41+
<ul></ul>
42+
<h1>FlyWeight</h1>
43+
</div>
44+
45+
46+
<script type="text/javascript" src="../statics/js/utils.js"></script>
47+
<script type="text/javascript" src="dist/scripts/main.js"></script>
48+
</body>
49+
</html>

Flyweight/scripts/Forest.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import TreeFactory from './TreeFactory';
2+
import Tree from './Tree';
3+
4+
const privateTrees = new WeakMap();
5+
class Forest {
6+
constructor() {
7+
privateTrees.set(this, []);
8+
}
9+
get trees() {
10+
return privateTrees.get(this);
11+
}
12+
plantTree(x, y, name, color, treeConfig) {
13+
const type = TreeFactory.getTreeType(name, color, treeConfig);
14+
const tree = new Tree(x, y, type);
15+
this.trees.push(tree);
16+
}
17+
render(canvas) {
18+
this.trees.forEach((tree) => {
19+
tree.render(canvas);
20+
});
21+
}
22+
}
23+
24+
export default Forest;

Flyweight/scripts/Tree.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const privateX = new WeakMap();
2+
const privateY = new WeakMap();
3+
const privateTreeType = new WeakMap();
4+
5+
class Tree {
6+
constructor(x = 0, y = 0, treeType) {
7+
privateX.set(this, x);
8+
privateY.set(this, y);
9+
privateTreeType.set(this, treeType);
10+
}
11+
get x() {
12+
return privateX.get(this);
13+
}
14+
get y() {
15+
return privateY.get(this);
16+
}
17+
get treeType() {
18+
return privateTreeType.get(this);
19+
}
20+
render(canvas) {
21+
const context = canvas.getContext("2d");
22+
this.treeType.render(context, this.x, this.y);
23+
}
24+
}
25+
26+
export default Tree;

Flyweight/scripts/TreeFactory.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import TreeType from './TreeType';
2+
3+
const treeTypesMap = new Map();
4+
class TreeFactory {
5+
static getTreeType(name, color, treeConfig) {
6+
let result = treeTypesMap.get(name);
7+
if(result == null) {
8+
result = new TreeType(name, color, treeConfig);
9+
treeTypesMap.set(name, result);
10+
}
11+
return result;
12+
}
13+
}
14+
15+
export default TreeFactory;

Flyweight/scripts/TreeType.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const privateName = new WeakMap();
2+
const privateColor = new WeakMap();
3+
const privateTreeConfig = new WeakMap();
4+
5+
class TreeType {
6+
constructor(name, color, treeConfig) {
7+
privateName.set(this, name);
8+
privateColor.set(this, color);
9+
privateTreeConfig.set(this, treeConfig);
10+
}
11+
get name() {
12+
return privateName.set(this);
13+
}
14+
get color() {
15+
return privateColor.set(this);
16+
}
17+
get treeConfig() {
18+
return privateTreeConfig.set(this);
19+
}
20+
render(context, x, y) {
21+
context.fillStyle = "black";
22+
context.fillRect(x - 1, y, 3, 5);
23+
}
24+
}
25+
26+
export default TreeType;

Flyweight/scripts/main.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Forest from './Forest';
2+
3+
const CANVAS_SIZE = 600;
4+
const TREES_TO_DRAW = 99900;
5+
const TREE_TYPES = 2;
6+
const forest = new Forest();
7+
8+
const getAmountOfTreesToRender = (amount, types) => {
9+
return Math.floor(amount / types);
10+
};
11+
12+
const random = (min, max) => {
13+
return min + (Math.random() * ((max - min) + 1));
14+
}
15+
const renderForest = (forest, canvas) => {
16+
for(let i = 0; i < getAmountOfTreesToRender(TREES_TO_DRAW, TREE_TYPES); i++) {
17+
forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE), 'Red Maple', 'red', 'Red Maple texture');
18+
forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE), 'Gray Birch', 'gray', 'Gray Birch texture stub');
19+
}
20+
21+
forest.render(canvas);
22+
23+
console.log(TREES_TO_DRAW + ' trees rendered');
24+
console.log('Memory usage:');
25+
console.log('Tree size (8 bytes) * ' + TREES_TO_DRAW + '+ TreeTypes size (~30 bytes) * ' + TREE_TYPES);
26+
console.log('Total: ' + ((TREES_TO_DRAW * 8 + TREE_TYPES * 30) / 1024 / 1024) + 'MB (instead of ' + ((TREES_TO_DRAW * 38) / 1024 / 1024) + 'MB)');
27+
}
28+
29+
renderForest(new Forest(), document.createElement('canvas'));

0 commit comments

Comments
 (0)