• JS设计模式之接口


    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控制的几种页面跳转方式和传值
    文件管理
    文件:文件和文件夹
    上传文件
    购物车的例子
    使用ajax登录格式
    ajax 另外两种返回类型(json xml)
    省级三级联动
    thinkPHP--SQL连贯操作
    thinkPHP-空操作
  • 原文地址:https://www.cnblogs.com/coiorz/p/4811569.html
Copyright © 2020-2023  润新知