`
xiao_Yao
  • 浏览: 11647 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

重读《javascript设计模式》之第二章(读书笔记)

阅读更多

第二章、接口

本章简要介绍了接口在面向对象编程的作用,好处。以及在javascirp中的接口的利弊。同时介绍了javacript中实现接口的方法。

 

面向对象设计的第一条原则

接口是面向对象javascript程序员的工具箱中最有用的工具之一。Gof在书中提到,面向对象设计的第一条原则就是:“针对接口编程而不是实现编程”。

 

javascript 没有接口

然而javascript本身没有内置的创建或实现接口的方法。也就说javascript本身是没有接口的。不过、由于javascript有强大的灵活性,最终我们可以在javascript中模拟实现接口。


 

接口定义,什么是接口

接口提供了一种用来说明一个对象应该具有的哪些方法的手段,它可以表明这些方法的语义,但是不规定这些方法的具体实现。呵呵感觉不怎么专业,很拗口呀。

 

接口利弊

先讲好处:

1、接口能促进代码重用

2、可以稳定不用类之间的通信方式

3、方便测试和调试

坏处:

1、接口强化了类型的作用,降低了javascript语言的灵活性。

2、javascript 没有原生的接口支持

3、javascript模仿接口带来性能的影响

4、javascript不能强制其他程序员遵守你的接口定义(这个要靠行政手段,呵呵)

 

其他语言的接口实现

其他语言基本使用了interface和implements关键字,内置支持。

 

javascript中模仿接口的方法

1、用注释描述接口

用注释模仿接口是最简单的方法,就是在注释里面写上接口的定义信息。这个超级简单,但效果就不怎么地了。

例子如下:

/**
//这里是接口的描述
interface XXXInterFace{
function add(child);
function remove(child);
}
*/
var XXXClass=function(){//implements XXXInterFace 说明实现了接口

}
XXXClass.prototype.add=function(){
......
}
XXXClass.prototype.remove=function(){
......
}
 

2、用属性检查模仿接口

这个方法比第一个要严谨一些。所有的类必须明确的声明自己实现的接口。虽然接口依旧是注释,但是你可以检查某个属性得知实现了什么样的接口。

 

/**
//这里是依旧是接口的描述
interface XXXInterFace{
function add(child);
function remove(child);
}
*/
var XXXClass-function(){
      this.implementsInterfaces=["XXXInterFace"];//申明实现的接口
}
XXXClass.prototype.add=function(){
......
}
XXXClass.prototype.remove=function(){
......
}
//调用类的方法
function dosome(xxxClassInstance){
      if(!implements(xxxClassInstance,"XXXInterFace")){//检查实现的接口
            alert("没有实现 XXXInterFace")
      }
}

function implements(obj){//检查实现的接口的方法
      ......

}
 

3、鸭式辨型模仿接口

鸭式辨型(鸭子测试DUCK TEST)——像鸭子一样走路并且嘎嘎叫的就是鸭子。呵呵这个很有意思,书上说的,这个是james Whitcomb Riley的名言。大家都知道这个大神不?我google了一下,并在前面的连接上加上了基维百科的连接。

 写道
美国印第安纳诗人詹姆斯·惠特科姆·莱利(1849-1916)可能发明了这个说法。他写道:“当我看到一只鸟,它走路像鸭子,游泳像鸭子,叫声像鸭子,我就称其为鸭子。”

 

言归正传,这个方法比较前面来说,不用借助于注释,而且可以强制实施,但是多了辅助的工具类InterFace和一个辅助函数ensureImplements

//定义申明接口
var   XXXInterFace=new InterFace("XXXInterFace",["add","remove"]);

//调用方法
function doSome(instance){
       ensureImplements(instance,XXXInterFace);//接口检查
}
 

 

 

4、本书的接口实现,Interface类

书中使用了第一中和第三种的结合,也就是我既写好了注释告诉你我实现的接口,也用到了鸭子辨型的接口检查。呵呵也就是要我们要是用接口的话,也可以模仿这样来实现。还有就是提醒大家注意好好写写注释。

书中具体的InterFace类如下:

// Constructor.呵呵抄不下去了网上下了源代码

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; 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]);        
    }    
};    

// Static class method.

Interface.ensureImplements = function(object) {
    if(arguments.length < 2) {
        throw new Error("Function Interface.ensureImplements called with " + 
          arguments.length  + "arguments, but expected at least 2.");
    }

    for(var i = 1, len = arguments.length; 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.");
            }
        }
    } 
};
 

 

 

依赖接口的设计模式

工厂模式

组合模式

装饰者模式

命令模式

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics