zoukankan      html  css  js  c++  java
  • 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命名的由来。

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

  • 相关阅读:
    ABP.NET 方法使用 HTTPPOST,HTTPGET,HTTPPUT 特性
    Asp.Net Core 获取配置系统的链接字符串
    ABP.NET CORE 框架 取消新增用户邮箱地址必填验证
    前端开发常用组件库
    微信RSA加密公钥API
    动手实现一个较为简单的MQTT服务端和客户端
    计算入职时间的时间算法
    Windows Terminal 安装及美化
    Windows10内置Linux子系统(WSL)安装
    分享powershell设定网卡,ip,网关,dns的命令
  • 原文地址:https://www.cnblogs.com/coiorz/p/4811569.html
Copyright © 2011-2022 走看看