标签:style blog color io os 使用 java ar strong
javascript 采用设计模式主要有下面的三方面原因:
同时,滥用设计模式也会带来一些后果:
实现容易,合理使用才是难点。一个建议就是:尽量选用最合适的那种,但不要过度的牺牲性能。
接口:接口是用来说明该对象具有哪些方法的手段,尽管其表明这些方法的语义,但是它不规定实现。
在Javascript中模仿接口
一:用注释描述接口
/* interface Composite{ function add(child); function remove(child); function getChild(index); } interface FormItem{ function save(); } */ var CompositeForm = function(id,method,action){ } CompositeForm.prototype.add = function(){ } CompositeForm.prototype.remove = function(){ } CompositeForm.prototype.getChild = function(){ } CompositeForm.prototype.save = function(){ }
这种模仿只是停留在文档阶段。没有对是否实现正确的方法进行检查,也不会抛出错误,完全依靠自觉。
二:用属性检查模仿接口:
/* interface Composite{ function add(child); function remove(child); function getChild(index); } interface FormItem{ function save(); } */ var CompositeForm = function(id,method,action){ this.implementsInterfaces = [‘Composite‘,‘FormItem‘]; } function addForm(formInstance){ if(!implements(formInstance,‘Composite‘,‘FormItem‘){ throw new Error("Object does not implement a required interface."); }) } function implements(object){ for(var i=1;i<arguments.length;i++){ var interfaceName = argument[i]; var interfaceFound = false; for(var j=0;j<object.implementsInterfaces.length;j++){ if(object.implementsInterfaces[j]==interfaceName){ interfaceFound = true; break; } } //有接口没有找到 if(!interfaceFound){ return false; } } //找到了所有的接口 return true; }
这里,CompositeForm 宣称自己实现了‘Composite‘,‘FormItem‘这俩个接口,其做法是把这俩个接口的名称加入到一个对象的数组中,显式的声明自己支持的接口。
任何一个要求其参数属于特定类型的函数都可以对这个属性进行检查,并在找不到实现方法的时候,抛出异常。
三、鸭式辨型模仿接口
它把对象实现的方法集作为判断它是不是某个类的唯一标准,这种方法背后的观点很简单:如果对象具有与接口定义的方法同名的所有方法,那么就可以认为它实现了这个接口。
Interface 类的定义
/* * 定义接口方法 */ var Interface = function(name,methods){ if(arguments.length!=2){ throw new Error("Interface constructor called with " + arguments.length + "arguments, but expected exactly 2."); }; this.name = name ; this.methods = []; for (var i = 0,len = methods.length - 1; i < len; i++) { if(typeof methods[i]!==‘string‘){ throw new Error("Interface constructor expects method names to be " + "passed in as a string."); } this.methods.push(methods[i]); }; }; /* * 给Interface扩展静态验证方法 */ Interface.ensureImplements = function(obj){ if(arguments.length<2){ throw new Error("Function Interface.ensureImplements called with " + arguments.length + "arguments, but expected at least 2."); }; for (var i = 0,len = methods.length - 1; i < len; i++) { var interface = arguments[i]; if(interface.constructor!==interface){ throw new Error("Function Interface.ensureImplements expects arguments " + "two and above to be instances of Interface."); }; for (var j = 0,methodsLen = interface.methods.length; j<methodsLen; j++) { var method = interface.methods[j]; if(!object[method]||typeof object[method] !== ‘function‘){ throw new Error("Function Interface.ensureImplements: object " + "does not implement the " + interface.name + " interface. Method " + method + " was not found."); }; }; }; }
继承
链式继承的实现
function extend(subClass,superClass){ var F = function(){}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.peototype.constructor = subClass; subClass.superclass = superClass.prototype; if(superClass.prototype.constructor == Object.prototype.constructor){ superClass.prototype.constructor = superClass; } }
superclass 用来弱化子类和超类之间的耦合。同时确保超类的constructor被正确设置。
原型继承的实现,实际上是拷贝继承,实现方式如下。
function clone(object){ function F(){}; F.prototype = object; return new F; }
实际上返回的是一个以给定对象为原生对象的空对象。
掺元类的实现。有一种重用的方法不需要用到严格的继承,如果想把一个函数用到多个类中,可以扩充的方式让这些类共享该函数,做法:先创建一个包含各种通用方法的类,然后再用它扩充其他的类,这种包含通用方法的类称为掺元类。
掺元类的实现方法:
function augment(receivingClass,givingClass){ //if has the third arg if(arguments.length[2]){ for(var i=2,len = arguments.length;i<len;i++){ receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; } }else{ for(methodName in givingClass.prototype){ if(!receivingClass.prototype[methodName]){ receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } }
封装
封装就是对对象内部的数据表现形式和实现细节进行隐藏。如果想访问封装过的对象,只能使用已定义的操作这一种方式。
在javascript中,我们没有关键字,只能使用闭包的概念来创建私有的属性和方法。
javascript 想创建对象的基本模式有三种。
门户大开式,用下划线表示私有方法和属性,用闭包来创建真正的私有成员。
var Book = function(newIsbn,newTitle,newAuthor){ //私有属性 var isbn,title,anthor; function checkIsbn(isbn){ ... }; //特权方法,可以访问私有变量 this.getIsbn = function(){ return isbn; }; this.setIsbn = function(){ if(!checkIsbn(newIsbn)) throw new Error(‘Book:Invalid ISBN.‘); isbn = newIsbn; }; this.getTitle = function(){ return newTitle; }; this.setTitle = function(newTitle){ title = newTiyle||‘‘; }; this.getAuthor = function(){ return author; }; this.setAuthor = function(newAuthor){ author = newAuthor||‘‘; }; this.setIsbn(newIsbn); this.setTitle(newTitle); this.setAuthor(newAuthor); } //不需要直接访问私有属性的方法都可以在prototype中声明。 Book.prototype = { display:function(){...} }
更高级的对象创建。
var Book = (function(){ //私有静态属性 var numOfBooks = 0; //私有静态方法 function checkIsbn(isbn){ ... }; return function(newIsbn,newTitle,newAuthor){ //私有属性 var isbn,title,anthor; //特权方法,可以访问私有变量 this.getIsbn = function(){ return isbn; }; this.setIsbn = function(){ if(!checkIsbn(newIsbn)) throw new Error(‘Book:Invalid ISBN.‘); isbn = newIsbn; }; this.getTitle = function(){ return newTitle; }; this.setTitle = function(newTitle){ title = newTiyle||‘‘; }; this.getAuthor = function(){ return author; }; this.setAuthor = function(newAuthor){ author = newAuthor||‘‘; }; numOfBooks++; if(numOfBooks > 50) throw new Err(‘Book:only 50 instances of Book can be created.‘); this.setIsbn(newIsbn); this.setTitle(newTitle); this.setAuthor(newAuthor); } })(); //不需要直接访问私有属性的方法都可以在prototype中声明。 Book.prototype = { display:function(){...} }
一些简单的说明:
读书笔记之 - javascript 设计模式 - 接口、封装和链式调用
标签:style blog color io os 使用 java ar strong
原文地址:http://www.cnblogs.com/mrsai/p/3988214.html