享元模式实际上是一种优化模式,目的在于提高系统的性能和代码的效率。
使用享元模式的条件:最重要的条件是网页中必须使用了大量资源密集型对象,如果只会用到了少许这类对象,那么这种优化并不划算。第二个条件是这些对象中所保存的数据至少有一部分能被转换为外在的数据。最后一个条件是,将外在的数据分离出去以后,独一无二的对象的数目相对减少。
使用享元模式的步骤:1、将所有外在的数据从目标类剥离。2、创建一个用来控制该类的实例化工厂。3、创建一个用来保存外在数据的管理器。
实例:工具提示对象。(Tooltip)
先看一个没有用到享元模式的例子。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>工具提示对象</title> <style type="text/css"> .test-div{ width:100px; heiht:30px;text-align:center; line-height: 30px; cursor: pointer;border:1px solid #101010; margin-top:20px; } .tooltip{ height:20px; line-height: 20px; border: 1px solid #ccc; border-radius: 2px; font-family: monospace; font-size: 12px; background: #ddd; padding:2px 5px; } </style> </head> <body> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> </body> </html> <script type="text/javascript"> window.onload = function(){ var aDiv = document.getElementsByTagName("div"); for(var i = 0 , len = aDiv.length;i<len;i++){ new Tooltip(aDiv[i],"this is a div, the index is:" + i); } } var Tooltip = function(targetElement,text){ this.target = targetElement; this.text = text; this.delayTimeout = null; // show tooltip timer this.delay = 500; // 延时时长 //create the html this.element = document.createElement("div"); this.element.style.display = "none"; this.element.style.position = "absolute"; this.element.className = "tooltip"; document.getElementsByTagName("body")[0].appendChild(this.element); this.element.innerHTML = this.text; //attach the events var that = this; this.target.addEventListener("mouseover",function(e){ that.startDelay(e); }); this.target.addEventListener("mouseout",function(){ that.hide(); }) }; Tooltip.prototype = { startDelay:function(e){ if(this.delayTimeout == null){ var that = this; var x = e.clientX; var y = e.clientY; this.delayTimeout = setTimeout(function(){ that.show(x,y); },this.delay); } }, show:function(x,y){ clearTimeout(this.delayTimeout); this.element.style.left = x + "px"; this.element.style.top = y + "px"; this.element.style.display = "block"; }, hide:function(){ clearTimeout(this.delayTimeout); this.delayTimeout = null; this.element.style.display = "none"; } } </script>
结果:把鼠标放到每个div上以后,用debug查看element元素,会发现生成很多tooltip的div。
使用享元模式以后:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>工具提示对象</title> <style type="text/css"> .test-div{ width:100px; heiht:30px;text-align:center; line-height: 30px; cursor: pointer;border:1px solid #101010; margin-top:20px; } .tooltip{ height:20px; line-height: 20px; border: 1px solid #ccc; border-radius: 2px; font-family: monospace; font-size: 12px; background: #ddd; padding:2px 5px; } </style> </head> <body> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> <div class="test-div">test div</div> </body> </html> <script type="text/javascript" src="ToolTip.js"></script> <script type="text/javascript"> window.onload = function(){ var aDiv = document.getElementsByTagName("div"); for(var i = 0 , len = aDiv.length;i<len;i++){ TooltipManager.addTooltip(aDiv[i],"this is a div, the index is:" + i); } } </script>
对应的js:
1 var TooltipManager = (function(){ 2 var storedInstance = null; 3 4 /*Tooltip class*/ 5 var Tooltip = function(){ 6 this.delayTimeout = null; // show tooltip timer 7 this.delay = 500; // 延时时长 8 9 //create the html 10 this.element = document.createElement("div"); 11 this.element.style.display = "none"; 12 this.element.style.position = "absolute"; 13 this.element.className = "tooltip"; 14 document.getElementsByTagName("body")[0].appendChild(this.element); 15 }; 16 17 Tooltip.prototype = { 18 startDelay:function(e,text){ 19 if(this.delayTimeout == null){ 20 var that = this; 21 var x = e.clientX; 22 var y = e.clientY; 23 this.delayTimeout = setTimeout(function(){ 24 that.show(x,y,text); 25 },this.delay); 26 } 27 }, 28 show:function(x,y,text){ 29 clearTimeout(this.delayTimeout); 30 this.element.style.left = x + "px"; 31 this.element.style.top = y + "px"; 32 this.element.style.display = "block"; 33 this.element.innerHTML = text; 34 }, 35 hide:function(){ 36 clearTimeout(this.delayTimeout); 37 this.delayTimeout = null; 38 this.element.style.display = "none"; 39 } 40 }; 41 42 return { 43 addTooltip:function(targetElement,text){ 44 var tt = this.getToolTip(); 45 targetElement.addEventListener("mouseover",function(e){tt.startDelay(e,text)}); 46 targetElement.addEventListener("mouseout",function(e){tt.hide()}); 47 }, 48 getToolTip:function(){ 49 if(null == storedInstance){ 50 storedInstance = new Tooltip(); 51 } 52 return storedInstance; 53 } 54 } 55 })();
结果:
结论:享元模式好处不言而喻。