• 《javascript设计模式》2接口


    /**
     * 接口是一种指定对象应该有哪些方法的技术,他不关心方法如何实现。
     * 基于接口编程的好处是:实现相同接口的对象,可以互换,而不影响功能实现。
     * 接口还有利于大项目中,多人合作的交流
     */
    /**************** 在js中模仿接口 ******************/
    
    //用注释描述接口
    //效果最差,不会提供错误信息
    //易于实现
    /*
     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) {
    
    };
    Composite.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) {
        //add interface into array
        this.implementsInterfaces = ['Composite', 'FormItem'];
        //...
    };
    
    function addForm(formInstance) {
        if (!implements(formInstance, 'Composite', 'formItem')) {
            throw new Error('Object does not implement a required interface.');
        }
        //...
    }
    
    //The implement function,which checks to see if an object declares that
    //it implements the required interface
    function implements(object) {
        //looping through all arguments after the first one
        for (var i = 1; i < arguments.length; i++) {
            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) {
                //an interface was not found
                return false;
            }
        }
        //all interface were found
        return true;
    }
    
    
    //用鸭式辩型模仿接口
    //如果对象具有与接口定义的方法同名的所有方法
    //那么就可以认为它实现了这个接口
    /**
     * 三种方法中最有用的一种
     * 缺点:
     *     类并不声明自己实现了那些接口,降低了代码的可重用性
     *     缺乏自我描述
     *     不检查方法的参数
     */
    //Interface.
    var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
    var FormItem = new Interface('FormItem', ['save']);
    
    //CompositeForm class
    var CompositeForm = function (id, method, action) {
        //...
    };
    //...
    function addForm(formInstance) {
        ensureImplements(formInstance, Composite, FormItem);
        //this function will throw an error if a required method is not implemented
        //...
    }
    
    
    //本书采用的接口实现方法
    //结合第一种和第三种方法
    //interfaces
    var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
    var formItem = new Interface('FormItem', ['save']);
    
    //CompositeForm class
    var CompositeForm = function (id, method, action) {
        //...
    };
    //...
    
    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
        //...
    }
    
    
    /************ Interface类 *************/
    //Constructor
    var Interface = function (name, method) {
        // 检测参数个数
        if (arguments.length != 2) {
            throw new Error('Interface constructor called with ' + arguments.length + 'arguments,ut expected exactly 2.');
        }
        this.name = name;
        this.methods = [];
        //遍历方法
        for (var i = 0, len = method.length; i < len; i++) {
            //检查数组值是否字符串
            //如果不是,抛出错误信息
            if (typeof method[i] !== 'string') {
                throw new Error('Interface constructor expects method names to be passed in as a string');
            }
            //将方法名添加到属性数组中
            this.methods.push(method[i]);
        }
    
    };
    
    //static class method
    Interface.ensureImplements = function (object) {
        //参数个数必须大于等于2个
        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];
            //如果不是Interface的实例,则抛出错误
            if (interface.constructor !== Interface) {
                throw new Error('Function interface.ensureImplements expectes 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];
                //如果object没有实例中的方法,则抛出错误
                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.');
                }
            }
        }
    };
    
    
    //使用
        var DynamicMap = new Interface('DybamicMap', ['centerOnPoint', 'zoom', 'draw']);
    
        function displayRoute(mapInstance) {
            Interface.ensureImplements(mapInstance, DynamicMap);
            mapInstance.centerOnPoint(12, 34);
            mapInstance.zoom(5);
            mapInstance.draw();
            //...
        }
        var Test = function () {
    
        };
        Test.prototype = {
            centerOnPoint:function (a, b) {
                console.log('centerOnPoint2');
            },
            zoom:function (num) {
                console.log('zoom2');
            },
            draw:function(){
    
            }
        };
        var a = new Test();
        displayRoute(a);
    
    
    //实例
    // ResultFormatter class,before we implement interface checking
    //未使用Interface类检测
    var TestResult = function () {
    
    };
    TestResult.prototype = {
        getDate:function () {
    
        },
        getResults:function () {
    
        }
    };
    var ResultFormatter = function (resultsObject) {
        // 是否为TestResult的实例
        // 不是就抛出错误
        if (!(resultsObject instanceof TestResult)) {
            throw new Error('ResultsFormatter: constructor requires an instance of TestResult as an argument.');
        }
        //将参数公有化
        this.resultsObject = resultsObject;
    };
    
    ResultFormatter.prototype.renderResults = function () {
        var dateOfTest = this.resultsObject.getDate();
        var resultsArray = this.resultsObject.getResults();
    
        var resultsContainer = document.createElement('div');
        var resultsHeader = document.createElement('h3');
        resultsHeader.innerHTML = 'Test Results from ' + dateOfTest.toUTCString();
        resultsContainer.appendChild(resultsHeader);
    
        var resultsList = document.createElement('ul');
        resultsContainer.appendChild(resultsList);
        for (var i = 0, len = resultsArray.length; i < len; i++) {
            var listItem = document.createElement('li');
            listItem.innerHTML = resultsArray[i];
            resultsList.appendChild(listItem);
        }
    
        //返回创建的DOM
        return resultsContainer;
    };
    /*
     TestResult类可能被修改,致使其不再拥有getDate()方法
     检查仍能通过,但renderResults方法却会失灵
     不允许其他类的实例作为参数
     */
    
    //使用Interface类后
    //ResultSet interface
    var ResultSet = new Interface('ResultSet', ['getDate', 'getResults']);
    
    //ResultFormatter class, after adding Interface checking
    var ResultFormatter = function (resultsObject) {
        Interface.ensureImplements(resultsObject, ResultSet);
        this.resultsObject = resultsObject;
    };
    
    ResultFormatter.prototype.renderResults=function(){
        //...
    };
    

      

  • 相关阅读:
    java 数据结构(一):java常用类 一 String类
    java 数据结构(三):java常用类 三 日期时间API
    java 数据结构(四):java常用类四 比较器以及其他类
    java 数据结构(五):数据结构简述
    Android开发 无法导入ViewPagerIndicator或其他开源框架无法导入
    开源控件ViewPagerIndicator的使用
    Android简易实战教程--第二十五话《网络图片查看器》
    The type org.apache.http.HttpResponse cannot be resolved. It is indirectly referenced from required
    Mac 下安装node.js
    Android简易实战教程--第二十四话《画画板》
  • 原文地址:https://www.cnblogs.com/webFrontDev/p/2820374.html
Copyright © 2020-2023  润新知