码迷,mamicode.com
首页 > Web开发 > 详细

JS设计模式之接口

时间:2015-09-15 23:25:09      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

JS能把类模仿得惟妙惟肖,也可以模仿接口,参考pro javascript design pattern一书,主要有3种方式

注释(Comment)

这种不用多说了,就是在注释里写明接口定义了哪些方法,哪些地方需要实现什么接口。好处是不会增加任何多的对象或函数,也不会影响执行效率。坏处也很明显,一切靠自觉,而且没有错误提示。

 

属性检查(Attribute Checking)

function Dog() {
    this.implementInterfaces = [‘Animal‘];
}

function play(dog) {
    implement(dog, ‘Animal‘);
    dog.eat();
    dog.run();
}

function implement(obj) {
    var interfaceName, interfaceFound, i, j, len;
    for (i = 1; i < arguments.length; i += 1) {
        interfaceName = arguments[i];
        interfaceFound = false;
        for (j = 0, len = obj.implementInterfaces.length; j < len; j += 1) {
            if (interfaceName == obj.implementInterfaces[j]) {
                interfaceFound = true;
                break;
            }
        }
        if (!interfaceFound) {
            throw new Error(interfaceName + " was not implemented");
        }
    }
}

这种方式的好处是有错误提示,但是仍然要靠自觉,即使检查通过了,也不能确保就真的实现了接口的方法。

 

Duck Typing

function Interface(name, methods) {
    var i, len;

    if (arguments.length !== 2) {
        throw new Error("exactly 2 arguments are expected");
    }

    this.name = name;
    this.methods = [];

    for (i = 0, len = methods.length; i < len; i += 1) {
        if (typeof methods[i] !== ‘string‘) {
            throw new Error("method name is expected to be passed in as a string");
        }
        this.methods.push(methods[i]);
    }
}

Interface.ensureImplements = function (obj) {
    var i, j, interface, method, l,
        len = arguments.length;

    if (len < 2) {
        throw new Error("at least 2 arguments are expected");
    }

    for (i = 1; i < len; i += 1) {
        interface = arguments[i];
        if (interface.constructor !== Interface) {
            throw new Error("instances of Interface are expected");
        }

        for (j = 0, l = interface.methods.length; j < l; j += 1) {
            method = interface.methods[j];
            if (typeof obj[method] !== ‘function‘) {
                throw new Error("Method " + method + "() of Interface " + interface.name + " was not found");
            }
        }
    }
};

var Animal = new Interface(‘Animal‘, [‘eat‘, ‘run‘]),
dog = new Dog(); Interface.ensureImplements(dog
, Animal);

"If it walks like a duck and quacks like a duck, it‘s a duck",这个方法不去管类有没有实现接口,而是把注意力放在实例上,毕竟接口里的方法最后都要落在实例上,只要确保实例含有同名方法,就认为它实现了接口,这也是duck type命名的由来。

 

接口的实现并不复杂,重要的是恰当的判断是否需要使用接口。

 

JS设计模式之接口

标签:

原文地址:http://www.cnblogs.com/coiorz/p/4811569.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!