小谈Javascript设计模式

4,882 views
4,749 views

Published on

javascript设计模式
javascript design patterns

Published in: Technology
2 Comments
19 Likes
Statistics
Notes
No Downloads
Views
Total views
4,882
On SlideShare
0
From Embeds
0
Number of Embeds
880
Actions
Shares
0
Downloads
109
Comments
2
Likes
19
Embeds 0
No embeds

No notes for slide

小谈Javascript设计模式

  1. 1. 小谈Javascript设计模式<br />鲁超伍|Adam<br />http://adamlu.com/<br />http://twitter.com/adamlu<br />
  2. 2. 为什么要使用设计模式<br />设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。<br />
  3. 3. 设计模式(Design Patterns)<br />工厂(Factory)模式<br />单体(Singleton)模式<br />装饰者(Decorator)模式<br />桥接(Bridge)模式<br />适配器(Adapter)模式<br />观察者(Observer)模式<br />门面(Façade)模式<br />策略(Strategy)模式<br />命令(Command)模式<br />职责链(Chain Of Responsibility)模式<br />组合(Composite)模式<br />享元(Flyweight)模式<br />……<br />
  4. 4. 工厂(Factory)模式<br />提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。<br />
  5. 5. Factory-EXP<br />if (typeofXMLHttpRequest != "undefined") {    return new XMLHttpRequest();} else if (typeofwindow.ActiveXObject != "undefined") {    return new ActiveXObject("MSXML2.XMLHttp");}<br />function XMLHttpFactory() {}XMLHttpFactory.createXMLHttp = function () {    if (typeofXMLHttpRequest != "undefined") {        return new XMLHttpRequest();    } else if (typeofwindow.ActiveXObject != "undefined") {        return new ActiveXObject("MSXML2.XMLHttp");    }} <br />varxmlhttp=XMLHttpFactory.createXMLHttp();<br />
  6. 6. 单体(Singleton)模式<br />保证一个类仅有一个实例,并提供一个访问它的全局访问点。<br />
  7. 7. Singleton-EXP<br />UserAgent = function UserAgent() { <br />var u = navigator.userAgent, d = document;<br /> this.ie = typeofd.all != "undefined";<br /> this.ns4 = typeofd.layers != "undefined";<br />this.dom = typeofd.getElementById != "undefined";<br />this.safari = /Safari/.test(u);<br />this.moz = /Gecko/.test(u) && !this.safari;<br />this.mie = this.ie && /Mac/.test(u);<br /> this.win9x = /Win9/.test(u) || /Windows 9/.test(u);<br /> this.o7 = /Opera 7/.test(u);<br />this.supported = (typeofd.write != "undefined") <br /> && (this.ie || this.ns4 || this.dom);<br />};<br />
  8. 8. Singleton-EXP<br />ua = new function UserAgent() {<br />var u = navigator.userAgent, d = document;<br /> this.ie = typeofd.all != "undefined";<br /> this.ns4 = typeofd.layers != "undefined";<br />this.dom = typeofd.getElementById != "undefined";<br />this.safari = /Safari/.test(u);<br />this.moz = /Gecko/.test(u) && !this.safari;<br />this.mie = this.ie && /Mac/.test(u);<br /> this.win9x = /Win9/.test(u) || /Windows 9/.test(u);<br /> this.o7 = /Opera 7/.test(u);<br />this.supported = (typeofd.write != "undefined") <br /> && (this.ie || this.ns4 || this.dom);<br />};<br />
  9. 9. 装饰者(Decorator)模式<br />动态地给一个对象添加一些额外的职责。就扩展功能而言, 它比生成子类方式更为灵活。 <br />
  10. 10. Decorator-EXP<br />// Create a Name Space myText = { }; <br />myText.Decorators = { }; // Core base class <br />myText.Core = function( myString ) {<br />this.show = function( ) { return myString; }; <br />} <br />// First Decorator, to add quesCon mark to string <br />myText.Decorators.addQuestionMark = function ( myString ) {<br />this.show = function( ){ return myString.show( ) + '?'; }; <br />} <br />//Second Decorator, to make string Italics <br />myText.Decorators.makeItalic = functioon( myString ) {<br />this.show = function(){ return "<i>" + myString.show( ) + "</i>"; }; <br />}<br />
  11. 11. Decorator-EXP<br />//Third Decorator, to make first character of sentence caps myText.Decorators.upperCaseFirstChar = function( myString ) {<br />this.show = function( ){ <br />varstr = myString.show( ); <br />varucf = str.charAt(0).toUpperCase( );<br />return ucf + str.substr( 1, str.length – 1 ); }; } <br />// Set up the core String <br />vartheString = new myText.Core( “this is a sample test string” ); <br />// Decorate the string with Decorators <br />theString = new myText.Decorator.upperCaseFirstChar( theString ); <br />theString = new myText.Decorator.addQuestionMark( theString ); <br />theString = new myText.Decorator.makeItalic( theString ); <br />theString.show(); <br />
  12. 12. 桥接(Bridge)模式<br />将抽象部分与它的实现部分分离,使它们都可以独立地变化。<br />
  13. 13. Bridge-EXP<br />addEvent(element, 'click', getBeerById);<br />function getBeerById(e) {<br />var id = this.id;<br />asyncRequest('GET', 'beer.uri?id=' + id, function(resp) {<br />// Callback response.<br />console.log('Requested Beer: ' + resp.responseText);<br />});<br />}<br />
  14. 14. Bridge-EXP<br />function getBeerById(id, callback) {<br />// Make request for beer by ID, then return the beer data.<br />asyncRequest('GET', 'beer.uri?id=' + id, function(resp) {<br />// callback response<br />callback(resp.responseText);<br />});<br />}<br />addEvent(element, 'click', getBeerByIdBridge);<br />function getBeerByIdBridge (e) {<br />getBeerById(this.id, function(beer) {<br />console.log('Requested Beer: '+beer);<br />});<br />}<br />
  15. 15. 适配器(Adapter)模式<br />将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 <br />
  16. 16. Adapter-EXP<br />function $(){};<br />function YAHOO.util.Dom.get=function(el){};<br />function prototypeToYuiAdapter(){      return YAHOO.util.Dom.get(arguments);    }<br />function YUIToPrototypeAdapter(el) { return $.apply(window, el); }<br />$ = prototypeToYuiAdapter;<br />YAHOO.util.Dom.get = YUIToPrototypeAdapter;<br />
  17. 17. 观察者(Observer)模式<br />定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。<br />
  18. 18. Observer-EXP<br />// The Observer Object – One who super sees all the print operations <br />function printManager( ) { <br />var queue = [ ]; <br />// The attach method <br />this.addJob = function(name, job) { queue.push( { ”name” : name, "job” : job } ); <br />} <br />// The detach method <br />this.removeJob = function(job) { <br />var _queue = [ ]; <br />for(var i in queue) { <br />if(queue[ i ].job == job) continue; else _queue.push( queue[ i ] ); <br />} <br />queue = _queue; <br />} <br />// The notify method <br />this.doPrint = function( item ) { <br />for ( var i in queue ) { queue[ i ].job.call( this, item );}} <br />} <br />
  19. 19. Observer-EXP<br />var p = new printManager(); // Publishers are in charge of "publishing” <br />function printWithItalics( str ) { // The callback function – the print job <br />alert( “<i>” + str + “</i>” ); <br />} <br />//Once subscribers are notified their callback functions are invoked<br />p.addJob( "italics", printWithItalics); <br />// Notify the observer about a state change <br />p.doPrint("this is a test"); <br />
  20. 20. 门面(Facade)模式<br />子系统中的一组接口提供一个一致的界面, 门面模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 <br />
  21. 21. Facade-EXP<br />function IEBrowser()  {this.hello=function(){alert(”IE browser”);}}function NonIEBrowser()  (this.hello =function(){alert(“NonIE browser”);}}var Facade={};Facade.hello=function(){var browser;if(window.ActiveXObject)  browser=new IEBrowser();else browser=new NonIEBrowser();Browser.hello(););<br />
  22. 22. 策略(Strategy)模式<br />定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。 <br />
  23. 23. Strategy-EXP<br />var Button = function(submit_func, label) {<br />this.label = label; <br /> return { <br />on_submit : function(numbers) { <br /> return submit_func(numbers);<br /> } <br /> };<br />};<br />var numbers = [1,2,3,4,5,6,7,8,9];<br />
  24. 24. Strategy-EXP<br />var sum = function(n) { <br />var sum = 0; <br /> for ( var a in n ) { <br /> sum = sum + n[a]; <br /> } <br /> return sum;<br />}; <br />var a = new Button(sum, "Add numbers");<br />var b = new Button(function(numbers) { <br /> return numbers.join(','); <br /> }, "test2");<br />a.on_submit(numbers);<br />b.on_submit(numbers);<br />
  25. 25. 命令(Command)模式<br />将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。 <br />
  26. 26. Command-EXP<br />var Calculator={<br />// addition<br />add: function(x,y) {<br />return x+y;<br />},<br />// subtraction<br />substract: function(x, y) {<br />return x-y;<br />},<br />// multiplication<br />multiply: function(x, y) {<br />return x*y;<br />},<br />// division<br />divide: function(x, y) {<br />return x/y;<br />},<br />};<br />
  27. 27. Command-EXP<br />Calculator.calc=function(command) {<br />return Calculator[command.type](command.opl,command.op2);<br />};<br />Calculator.calc({type: "add",opl:1,op2:1});<br />Calculator.calc({type: "Substract",opl:6,op2:2});<br />Calculator.calc({type: "multiply",opl:5,op2:2));<br />Calculator.calc({type: "divide",opl:8,op2:4));<br />
  28. 28. 职责链(Chain Of Responsibility)模式<br />为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。 <br />
  29. 29. 组合(Composite)模式<br />将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。 <br />
  30. 30. 享元(Flyweight)模式<br />运用共享技术有效地支持大量细粒度的对象。 <br />
  31. 31. 总结<br />设计模式不是哪种编程语言特有的,它同样可以应用于Javascrip,各种设计模式建立在面向对象编程的基础上,而设计模式应用于前端也是在最近几年,只有通过连续不断的软件开发实践我们才能够灵活的运用设计模式。<br />
  32. 32. 参考资源<br />http://www.www.digital-web.com/articles/excerpt_pro_javascript_patterns<br />http://aspalliance.com/1782_Working_with_GoFs_Design_Patterns_in_JavaScript_Programming.7<br />http://michaux.ca/articles/the-command-pattern-in-javascript-encapsulating-function-property-calls<br />http://en.wikipedia.org/wiki/Strategy_pattern#JavaScript<br />http://baike.baidu.com/view/66964.htm<br />http://www.slideshare.net/rmsguhan/javascript-design-patterns<br />
  33. 33. 谢谢!<br />

×