zoukankan      html  css  js  c++  java
  • JavaScript 实现接口 (Interfaces In JavaScript)

    接口是面向对象编程里的重要特性,遗憾的是JavaScript并没有提供对接口的支持!怎么实现接口呢?

    在实际中,我们可以在注释中定义好接口,在实际的代码中予以实现

    比如:

    /*
    interface Composite {
        function add(child);
        function remove(child);
        function getChild(index);
    }
    interface FormItem {
        function save();
    }
    */
    var CompositeForm = function(id, method, action) { // implements Composite, FormItem
    ...
    };
    // Implement the Composite interface.
    CompositeForm.prototype.add = function(child) {
    ...
    };
    CompositeForm.prototype.remove = function(child) {
    ...
    };
    CompositeForm.prototype.getChild = function(index) {
    ...
    };
    // Implement the FormItem interface.
    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.");
        }
    ...
    }
    // The implements function, which checks to see if an object declares that it
    // implements the required interfaces.
    function implements(object) {
        for(var i = 1; i < arguments.length; i++) { // Looping through all arguments
        // after the first one.
        var interfaceName = arguments[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; // An interface was not found.
            }
        }
        return true; // All interfaces were found.
    }
    

    这种方法让程序员在写的时候注明实现了哪些接口: this.implementsInterfaces = ['Composite', 'FormItem']; 在调用的时候使用implements方法来判断是否实现了,理论上可行,很有可能写上了实现了'Composite'接口,但是代码里却并没有add方法!因此,我们需要检验实现接口的类是否包含了接口里的方法!所以,接口必须从注释中解放出来:

    // Interfaces.
    var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
    var FormItem = new Interface('FormItem', ['save']);
    // CompositeForm class
    var CompositeForm = function(id, method, action) { // implements      Composite, FormItem
    ...
    };
    ...
    function addForm(formInstance) {
        Interface.ensureImplements(formInstance, Composite, FormItem);
        // This function will throw an error if a required method is not implemented,
        // halting execution of the function.
        // All code beneath this line will be executed only if the checks pass.
    ...
    }
    

        定义接口Composite,FormItem,并且CompositeForm实现这两个接口,在使用的时候,用Interface.ensureImplements来检验formInstance是否实现了这两个接口中的所有方法。

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

    为Interface 添加建议接口是否实现的静态方法

    // Constructor.
    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.");
            }
        }
        }
    };
    
  • 相关阅读:
    json作为参数传入函数
    js 获取input type="file" 选择的文件大小、文件名称、上次修改时间、类型等信息
    jquery 如何控制滚动条每次向下滚动300px
    [if lt IE 9]
    JS代码判断IE6,IE7,IE8,IE9!
    ios __block typeof 编译错误解决
    ios json结构
    iOS --创建文件夹 ,删除文件夹
    iOS --生产JSON格式,创建JSON文件,创建文件夹,指定储存
    转载 -- iOS开发之JSON格式数据的生成与解析
  • 原文地址:https://www.cnblogs.com/xiaoqi/p/1755084.html
Copyright © 2011-2022 走看看