Commits

Mort Yao committed 01f0cb8

add slides/flyweight-pattern

  • Participants
  • Parent commits 78a348e

Comments (0)

Files changed (11)

slides/flyweight-pattern/images/battlefield.jpg

Added
New image

slides/flyweight-pattern/images/example1_1.png

Added
New image

slides/flyweight-pattern/images/example1_2.png

Added
New image

slides/flyweight-pattern/images/flyweight.gif

Added
New image

slides/flyweight-pattern/images/flyweight.png

Added
New image

slides/flyweight-pattern/images/kickboxing1.jpg

Added
New image

slides/flyweight-pattern/images/m4a1.jpg

Added
New image

slides/flyweight-pattern/images/octocat.png

Added
New image

slides/flyweight-pattern/images/weapons.jpg

Added
New image

slides/flyweight-pattern/index.html

+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name="generator" content="pandoc">
+  <meta name="author" content="Mort Yao" />
+  <title>Flyweight Pattern</title>
+  <meta name="apple-mobile-web-app-capable" content="yes" />
+  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+  <link rel="stylesheet" href="reveal.js/css/reveal.min.css"/>
+    <style type="text/css">code{white-space: pre;}</style>
+    <style type="text/css">
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
+  margin: 0; padding: 0; vertical-align: baseline; border: none; }
+table.sourceCode { width: 100%; line-height: 100%; }
+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
+td.sourceCode { padding-left: 5px; }
+code > span.kw { color: #007020; font-weight: bold; }
+code > span.dt { color: #902000; }
+code > span.dv { color: #40a070; }
+code > span.bn { color: #40a070; }
+code > span.fl { color: #40a070; }
+code > span.ch { color: #4070a0; }
+code > span.st { color: #4070a0; }
+code > span.co { color: #60a0b0; font-style: italic; }
+code > span.ot { color: #007020; }
+code > span.al { color: #ff0000; font-weight: bold; }
+code > span.fu { color: #06287e; }
+code > span.er { color: #ff0000; font-weight: bold; }
+    </style>
+    <link rel="stylesheet" href="reveal.js/css/theme/simple.css" id="theme">
+  <link rel="stylesheet" media="print" href="reveal.js/css/print/pdf.css" />
+  <!--[if lt IE 9]>
+  <script src="reveal.js/lib/js/html5shiv.js"></script>
+  <![endif]-->
+</head>
+<body>
+  <div class="reveal">
+    <div class="slides">
+
+<section>
+    <h1 class="title">Flyweight Pattern</h1>
+    <h2 class="author">Mort Yao</h2>
+    <h3 class="date">Nov 18, 2013</h3>
+</section>
+
+<section id="flyweight-as-a-weight-class" class="slide level1">
+<h1>Flyweight as a Weight Class</h1>
+<figure>
+<img src="images/kickboxing1.jpg" />
+</figure>
+</section>
+<section id="weight-classes-in-mma" class="slide level1">
+<h1>Weight Classes in MMA</h1>
+<ul>
+<li class="fragment">Super Heavyweight</li>
+<li class="fragment">Heavyweight</li>
+<li class="fragment">Light Heavyweight</li>
+<li class="fragment">Middleweight</li>
+<li class="fragment">Welterweight</li>
+<li class="fragment">Lightweight</li>
+<li class="fragment">Featherweight</li>
+<li class="fragment">Bantamweight</li>
+<li class="fragment"><strong>Flyweight (&lt; 125 lb / 57 kg)</strong></li>
+</ul>
+</section>
+<section id="how-much-does-flyweight-weigh" class="slide level1">
+<h1>How much does Flyweight weigh?</h1>
+<ul>
+<li class="fragment">Lighter than Lightweight</li>
+</ul>
+</section>
+<section id="flyweight-as-a-design-pattern" class="slide level1">
+<h1>Flyweight as a Design Pattern</h1>
+<ul>
+<li class="fragment">Use case: build a 3D simulator</li>
+</ul>
+</section>
+<section id="gun-object" class="slide level1">
+<h1>Gun Object</h1>
+<figure>
+<img src="images/m4a1.jpg" />
+</figure>
+</section>
+<section id="gun-object-1" class="slide level1">
+<h1>Gun Object</h1>
+<ul>
+<li class="fragment">Weapon Type: Assault Rifle</li>
+<li class="fragment">Damage: 68 units</li>
+<li class="fragment">Magazine Size: 30 rounds</li>
+<li class="fragment">Reload Time: 2.03s (loaded); 2.36s (unloaded)</li>
+<li class="fragment">Rate of Fire: 800 rpm</li>
+<li class="fragment">...</li>
+<li class="fragment">3D models, textures, ...</li>
+</ul>
+</section>
+<section id="gun-object-2" class="slide level1">
+<h1>Gun Object</h1>
+<pre class="sourceCode java"><code class="sourceCode java"><span class="kw">class</span> M4A1 <span class="kw">implements</span> AssaultRifle {
+    <span class="kw">private</span> <span class="dt">int</span> damage = <span class="dv">68</span>;
+    <span class="kw">private</span> <span class="dt">int</span> magazineSize = <span class="dv">30</span>;
+    <span class="kw">private</span> <span class="dt">double</span> reloadTimeLoaded = <span class="fl">2.03</span>;
+    <span class="kw">private</span> <span class="dt">double</span> reloadTImeUnloaded = <span class="fl">2.36</span>;
+    <span class="kw">private</span> <span class="dt">double</span> rateOfFire = <span class="dv">800</span>;
+    ...
+    <span class="kw">private</span> BranchGroup model;
+    ...
+}</code></pre>
+<ul>
+<li class="fragment">1 object =&gt; 1 Megabyte in memory</li>
+</ul>
+</section>
+<section id="guns-lots-of-guns" class="slide level1">
+<h1>Guns, Lots of Guns</h1>
+<video width="640" height="480" controls>
+  
+<source src="videos/The Matrix Stockroom.webm" type="video/webm">
+</video>
+
+</section>
+<section id="guns-lots-of-guns-1" class="slide level1">
+<h1>Guns, Lots of Guns</h1>
+<ul>
+<li class="fragment">1,000 objects =&gt; 1 GB in memory</li>
+<li class="fragment"><p>1,000,000 objects =&gt; 1,000 GB = 1 TB in memory</p></li>
+<li class="fragment"><strong>Same object replicated, memory wasted</strong></li>
+<li class="fragment">Expensive</li>
+<li class="fragment"><p>Not applicable on real machines</p></li>
+</ul>
+</section>
+<section id="to-simulate-the-world" class="slide level1">
+<h1>To Simulate the World</h1>
+<ul>
+<li class="fragment">...of billions of objects</li>
+</ul>
+<figure>
+<img src="images/battlefield.jpg" />
+</figure>
+</section>
+<section id="to-simulate-the-world-1" class="slide level1">
+<h1>To Simulate the World</h1>
+<ul>
+<li class="fragment">No more repeated allocation of the same data</li>
+<li class="fragment">Reduce the amount of similar objects</li>
+<li class="fragment">Minimize the memory use</li>
+<li class="fragment"><strong>Flyweight</strong></li>
+</ul>
+</section>
+<section id="what-is-a-flyweight" class="slide level1">
+<h1>What is a Flyweight?</h1>
+<ul>
+<li class="fragment"><strong>Flyweight</strong>: An object that <strong>minimizes memory use</strong> by <strong>sharing</strong> as much data as possible with other similar objects. (Wikipedia)</li>
+<li class="fragment">Some parts of the object state are stored <strong>in external data structures</strong> and <strong>shared</strong>; they can be <strong>passed to the flyweight objects</strong> whenever needed.</li>
+</ul>
+</section>
+<section id="flyweight-design-motif" class="slide level1">
+<h1>Flyweight Design Motif</h1>
+<ul>
+<li class="fragment">Use <strong>sharing</strong> to support large numbers of fine-grained objects efficiently.</li>
+</ul>
+</section>
+<section id="flyweight-pattern-structure" class="slide level1">
+<h1>Flyweight Pattern: Structure</h1>
+<figure>
+<img src="images/flyweight.png" />
+</figure>
+</section>
+<section id="flyweight-pattern" class="slide level1">
+<h1>FLyweight Pattern</h1>
+<figure>
+<img src="images/flyweight.gif" />
+</figure>
+<ul>
+<li class="fragment"><strong>Flyweight</strong>: the Flyweight interface</li>
+<li class="fragment"><strong>ConcreteFlyweight</strong>: implements the Flyweight interface; stores <strong><em>intrinsic</em></strong> states and <strong><em>sharable</em></strong></li>
+<li class="fragment"><strong>UnsharedConcreteFlyweight</strong>: implements the Flyweight interface; <strong><em>unshared</em></strong></li>
+<li class="fragment"><strong>FlyweightFactory</strong>: creates and manages flyweight <strong><em>objects</em></strong></li>
+<li class="fragment"><strong>Client</strong>: maintains <strong><em>references</em></strong> to flyweight objects and stores their <strong><em>extrinsic</em></strong> state</li>
+</ul>
+</section>
+<section id="example-1-characters-in-word-processors" class="slide level1">
+<h1>Example 1: Characters in Word Processors</h1>
+<ul>
+<li class="fragment">(From the <em>GoF</em> book)</li>
+<li class="fragment">A <strong>glyph object</strong> for graphical representation of each character in a document:</li>
+</ul>
+<ol type="1">
+<li class="fragment">font outline</li>
+<li class="fragment">font metrics</li>
+<li class="fragment">other formatting data</li>
+</ol>
+<ul>
+<li class="fragment">A document could contain thousands of characters or even more</li>
+<li class="fragment">Too many character objects = huge memory consumption</li>
+</ul>
+</section>
+<section id="example-1" class="slide level1">
+<h1>Example 1</h1>
+<figure>
+<img src="images/example1_1.png" />
+</figure>
+<ul>
+<li class="fragment">Solution: <strong>shared objects</strong></li>
+</ul>
+</section>
+<section id="example-1-1" class="slide level1">
+<h1>Example 1</h1>
+<figure>
+<img src="images/example1_2.png" />
+</figure>
+<ul>
+<li class="fragment"><strong>Flyweight Pool</strong>: shared objects are stored in a pool</li>
+<li class="fragment">Clients maintains <strong><em>references</em></strong> to flyweight objects in the pool, rather than maintains <strong><em>objects</em></strong> directly.</li>
+</ul>
+</section>
+<section id="example-2-string-interning" class="slide level1">
+<h1>Example 2: String Interning</h1>
+<p>Java Strings (<strong>not interned</strong>)</p>
+<pre class="sourceCode java"><code class="sourceCode java"><span class="co">// Not interned</span>
+String s1 = <span class="kw">new</span> String(<span class="st">&quot;foo&quot;</span>);
+String s2 = <span class="kw">new</span> String(<span class="st">&quot;foo&quot;</span>);
+
+<span class="kw">if</span> (s1 == s2) {} <span class="co">// Not equal!</span>
+
+<span class="kw">if</span> (s1.<span class="fu">equals</span>(s2)) {} <span class="co">// Equal!</span></code></pre>
+<ul>
+<li class="fragment"><code>s1</code> and <code>s2</code> are references to two different objects (<code>s1 != s2</code>)</li>
+</ul>
+</section>
+<section id="example-2-string-interning-1" class="slide level1">
+<h1>Example 2: String Interning</h1>
+<p>Java Strings (<strong>interned</strong>)</p>
+<pre class="sourceCode java"><code class="sourceCode java"><span class="co">// Interned</span>
+String s1 = <span class="st">&quot;foo&quot;</span>;
+String s2 = <span class="st">&quot;foo&quot;</span>;
+
+<span class="kw">if</span> (s1 == s2) {} <span class="co">// Equal!</span>
+
+<span class="kw">if</span> (s1.<span class="fu">equals</span>(s2)) {} <span class="co">// Equal!</span></code></pre>
+<ul>
+<li class="fragment"><code>s1</code> and <code>s2</code> are references to the same object (<code>s1 == s2</code>)</li>
+<li class="fragment">this shared object is stored in the <strong>string intern pool</strong> and maintained by JVM</li>
+</ul>
+</section>
+<section id="example-2-string-interning-2" class="slide level1">
+<h1>Example 2: String Interning</h1>
+<ul>
+<li class="fragment">Storing only one copy of each distinct string value</li>
+<li class="fragment"><strong>String Interns</strong>: Flyweight objects</li>
+<li class="fragment"><strong>String Intern Pool</strong>: Flyweight pool</li>
+<li class="fragment"><strong>Language VM (JVM)</strong>: <em>FlyweightFactory</em> that manages the flyweight pool</li>
+</ul>
+</section>
+<section id="example-2-string-interning-3" class="slide level1">
+<h1>Example 2: String Interning</h1>
+<p><strong>Benefits:</strong></p>
+<ol type="1">
+<li class="fragment">Less memory usage (when the same string value is created and used a lot)</li>
+<li class="fragment">Faster access (<em>stack</em> vs. <em>heap</em>)</li>
+<li class="fragment">Faster value comparision (<em>reference comparison</em> always faster than <em>char-by-char comparison</em>)</li>
+</ol>
+</section>
+<section id="example-2-string-interning-4" class="slide level1">
+<h1>Example 2: String Interning</h1>
+<p>Languages with support for string interning:</p>
+<ul>
+<li class="fragment">Java</li>
+<li class="fragment">C#</li>
+<li class="fragment">Python</li>
+<li class="fragment">Ruby</li>
+<li class="fragment">Lisp / Scheme</li>
+<li class="fragment">...</li>
+</ul>
+</section>
+<section id="example-3-3d-simulation" class="slide level1">
+<h1>Example 3: 3D Simulation</h1>
+<p>Lots of Objects</p>
+<figure>
+<img src="images/weapons.jpg" />
+</figure>
+</section>
+<section id="example-3-3d-simulation-1" class="slide level1">
+<h1>Example 3: 3D Simulation</h1>
+<ul>
+<li class="fragment">A simple WebGL demo</li>
+<li class="fragment">Rendering a lot of cubes</li>
+</ul>
+</section>
+<section id="example-3" class="slide level1">
+<h1>Example 3</h1>
+<p>A cube object consists of:</p>
+<ul>
+<li class="fragment"><strong>Geometry</strong></li>
+<li class="fragment"><strong>Material</strong></li>
+<li class="fragment"><strong>Mesh</strong>, constructed from the geometry and the material</li>
+</ul>
+</section>
+<section id="example-3-1" class="slide level1">
+<h1>Example 3</h1>
+<p><strong>Geometry</strong>: shared, <strong><em>flyweight</em></strong> object</p>
+<pre class="sourceCode javascript"><code class="sourceCode javascript">geometry = <span class="kw">new</span> <span class="ot">THREE</span>.<span class="fu">CubeGeometry</span>(<span class="dv">20</span>, <span class="dv">20</span>, <span class="dv">20</span>);
+<span class="kw">for</span> (<span class="kw">var</span> i = <span class="dv">0</span>, l = <span class="ot">geometry</span>.<span class="ot">faces</span>.<span class="fu">length</span>; i &lt; l; i++) {
+    <span class="kw">var</span> face = <span class="ot">geometry</span>.<span class="fu">faces</span>[i];
+    <span class="ot">face</span>.<span class="fu">vertexColors</span>[<span class="dv">0</span>] = <span class="kw">new</span> <span class="ot">THREE</span>.<span class="fu">Color</span>().<span class="fu">setHSL</span>(
+        <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.2</span> + <span class="fl">0.5</span>, <span class="fl">0.75</span>, <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.25</span> + <span class="fl">0.75</span>);
+    <span class="ot">face</span>.<span class="fu">vertexColors</span>[<span class="dv">1</span>] = <span class="kw">new</span> <span class="ot">THREE</span>.<span class="fu">Color</span>().<span class="fu">setHSL</span>(
+        <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.2</span> + <span class="fl">0.5</span>, <span class="fl">0.75</span>, <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.25</span> + <span class="fl">0.75</span>);
+    <span class="ot">face</span>.<span class="fu">vertexColors</span>[<span class="dv">2</span>] = <span class="kw">new</span> <span class="ot">THREE</span>.<span class="fu">Color</span>().<span class="fu">setHSL</span>(
+        <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.2</span> + <span class="fl">0.5</span>, <span class="fl">0.75</span>, <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.25</span> + <span class="fl">0.75</span>);
+}</code></pre>
+</section>
+<section id="example-3-2" class="slide level1">
+<h1>Example 3</h1>
+<p><strong>Material</strong>: unshared object</p>
+<pre class="sourceCode javascript"><code class="sourceCode javascript">material = <span class="kw">new</span> <span class="ot">THREE</span>.<span class="fu">MeshPhongMaterial</span>({
+    <span class="dt">specular</span>: <span class="bn">0xffffff</span>,
+    <span class="dt">shading</span>: <span class="ot">THREE</span>.<span class="fu">FlatShading</span>,
+    <span class="dt">vertexColors</span>: <span class="ot">THREE</span>.<span class="fu">VertexColors</span>});
+<span class="ot">material</span>.<span class="ot">color</span>.<span class="fu">setHSL</span>(<span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.2</span> + <span class="fl">0.5</span>,
+    <span class="fl">0.75</span>, <span class="ot">Math</span>.<span class="fu">random</span>() * <span class="fl">0.25</span> + <span class="fl">0.75</span>);</code></pre>
+</section>
+<section id="example-3-3" class="slide level1">
+<h1>Example 3</h1>
+<p><strong>Mesh</strong>: constructed from <em>shared</em> <code>geometry</code> object and <em>unshared</em> <code>material</code> object</p>
+<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> mesh = <span class="kw">new</span> <span class="ot">THREE</span>.<span class="fu">Mesh</span>(geometry, material);
+<span class="ot">mesh</span>.<span class="ot">position</span>.<span class="fu">x</span> = <span class="ot">Math</span>.<span class="fu">floor</span>(<span class="ot">Math</span>.<span class="fu">random</span>() * <span class="dv">20</span> - <span class="dv">10</span>) * <span class="dv">20</span>;
+<span class="ot">mesh</span>.<span class="ot">position</span>.<span class="fu">y</span> = <span class="ot">Math</span>.<span class="fu">floor</span>(<span class="ot">Math</span>.<span class="fu">random</span>() * <span class="dv">20</span>) * <span class="dv">20</span> + <span class="dv">10</span>;
+<span class="ot">mesh</span>.<span class="ot">position</span>.<span class="fu">z</span> = <span class="ot">Math</span>.<span class="fu">floor</span>(<span class="ot">Math</span>.<span class="fu">random</span>() * <span class="dv">20</span> - <span class="dv">10</span>) * <span class="dv">20</span>;
+
+<span class="ot">scene</span>.<span class="fu">add</span>(mesh);
+<span class="ot">objects</span>.<span class="fu">push</span>(mesh);</code></pre>
+</section>
+<section id="example-3-4" class="slide level1">
+<h1>Example 3</h1>
+<ul>
+<li class="fragment">Some parts of the object state (&quot;intrinsic&quot;) are <em>shared</em></li>
+<li class="fragment"><p>One <code>geometry</code> object: all cubes have the same geometry</p></li>
+<li class="fragment">Other parts of the state are <em>unshared</em></li>
+<li class="fragment"><p>Many <code>mesh</code> and <code>material</code> objects: every cube has its own position and material</p></li>
+<li class="fragment"><strong>Flyweight</strong>: sharing as much data as possible with other similar objects</li>
+<li class="fragment"><p><strong>Minimizes memory use</strong> = Performance!</p></li>
+</ul>
+</section>
+<section id="thank-you" class="slide level1">
+<h1>Thank You</h1>
+<p><img src="images/octocat.png" height="60%"/></p>
+</section>
+<section id="references" class="slide level1">
+<h1>References</h1>
+<ul>
+<li class="fragment"><em>The GoF Book</em></li>
+<li class="fragment"><em>Wikipedia: Flyweight Pattern</em> <a href="https://en.wikipedia.org/wiki/Flyweight_pattern">https://en.wikipedia.org/wiki/Flyweight_pattern</a></li>
+<li class="fragment"><p><em>Awesome Q&amp;As on StackOverflow</em></p></li>
+<li class="fragment"><p><em>Three.js, a JavaScript 3D library</em> <a href="https://github.com/mrdoob/three.js">https://github.com/mrdoob/three.js</a></p></li>
+</ul>
+</section>
+    </div>
+  </div>
+
+  <script src="reveal.js/lib/js/head.min.js"></script>
+  <script src="reveal.js/js/reveal.min.js"></script>
+
+  <script>
+
+      // Full list of configuration options available here:
+      // https://github.com/hakimel/reveal.js#configuration
+      Reveal.initialize({
+        controls: true,
+        progress: true,
+        history: true,
+        center: true,
+        theme: 'beige', // available themes are in /css/theme
+        transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+        // Optional libraries used to extend on reveal.js
+        dependencies: [
+          { src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+          { src: 'reveal.js/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+          { src: 'reveal.js/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
+//          { src: 'reveal.js/plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; }, }
+//          { src: 'reveal.js/plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
+]});
+    </script>
+  </body>
+</html>