zoukankan      html  css  js  c++  java
  • JS设计模式——2.初识接口

    什么是接口

    接口提供了一种用以说明一个对象应该具有哪些方法的手段。

    接口之利

    1.接口具有自我描述性从而促进代码的重用

    2.接口有助于稳定不同中的类之间的通信方式

    3.测试和调试也变得更轻松

    接口之弊

    1.在一定程度上强化了类型的作用

    2.js中没有内置的interface,实现它会增加复杂度

    3.实现接口会对性能造成一定的影响

    4.无法强迫其他程序员遵守你定义的接口

    三种方法在JS中模仿接口

    注释法(这只是一种文档规范)

    /*
    interface Composite{
        function add(child);
        function remove(child);
        function getChild(index);
    }
    interface fromItem{
        function save();
    }
    */
    var CompositeForm = function(id, method, action){
        ...
    };
    CompositeForm.prototype.add = function(){
        ...
    };
    CompositeForm.prototype.remove = function(){
        ...
    };
    CompositeForm.prototype.getChild = function(){
        ...
    };
    CompositeForm.prototype.save = function(){
        ...
    };

    这种方法没有确保对象真正实现了正确的方法集而进行检查,也不会抛出错误以告知程序中有问题。

    用属性检查模仿接口

    /*
    interface Composite{
        function add(child);
        function remove(child);
        function getChild(index);
    }
    interface fromItem{
        function save();
    }
    */
    var CompositeForm = function(id, method, action){
        this.implementsInterfaces = ['Composite', 'FormItem']; //声明自己继承的接口
        ...
    };
    ...
    function addForm(formInstance){
        if(!implements(formInstance, 'Composite', 'FormItem')){ //检查实例formInstance是否实现了接口
            throw new Error('Object does not implement a required interface');
        }
    }
    function implements(object){ //检查算法,双重循环
        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){
                return false;
            }
        }
        return true;
    }

    这种做法是只知其表不知其里。

    用鸭式辨型模仿接口

    类是否声明自己支持哪些接口并不重要,只要它具有这些接口中的方法就行。

    var Composite = new Interface('Composite', ['add', 'remove', 'getChild']); //声明接口拥有的方法
    var FormItem = new Interface('FormItem', ['save']); //声明接口拥有的方法
    
    var compositeForm = function(id, method, action){//implements Composite, FormItem
        ...
    };
    ...
    function addForm(formInstance){
        ensureImplements(formInstance, Composite, formItem);
        ...
    }
    
    //Constructor
    var Interface = function(name, methods){ //将接口的方法保存在this.methods中用以将来的检测
        if(arguments.length != 2){
            throw new Error('Interface constructor called with '+arguments.legth+
                " arguments, but exected 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.ensureImplements = function(object){
        if(arguments.length < 2){
            throw new Error('Function Interface.ensureImplements called with'+arguments.length+
                "arugments, but expected at least 2.");
        }
        for (var i=0, len=arugments.length; i<len; i++){
            var intf = arguments[i];
            if(intf.constructor !== Interface){
                throw new Error('Function Interface.ensureImplements expects arguments'+
                    "two and above to be instances of Interface.");
            }
            for(var j=0; methodsLen = intf.methods.length; j<methodsLen; j++){ //通过methods检查实例是否实现了接口
                if(!object[method] || typeof object[method]!=='function'){
                    throw new Error('Function Interface.ensureImplements:object'+
                        " doesnot implement the"+intf.name+
                        " interface. Method"+method+" was not found!");
                }
            }
        }
    };

    嗯,这个方法还正规一点。但是要借助其它两个类,也没有声明自己实现哪了些接口,降低了重用性。

    一个例子

    这个例子确保我们在调用对象的方法时,它已经实现了相应的接口的方法。

    var DynamicMap = new Interface('DynamicMap', ['centerOnPoint', 'zoom', 'draw']);
    function displayRoute(mapInstance){
        Interface.ensureImplements(mapInstance, DynamicMap);
        mapInstance.centerOnPoint(12,34);
        mapInstance.zoom(5);
        mapInstance.draw();
        ...
    }
  • 相关阅读:
    fzuoj Problem 2177 ytaaa
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Capture the Flag
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Team Formation
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Beauty of Array
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Lunch Time
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Convert QWERTY to Dvorak
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest May Day Holiday
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Demacia of the Ancients
    zjuoj The 12th Zhejiang Provincial Collegiate Programming Contest Ace of Aces
    csuoj 1335: 高桥和低桥
  • 原文地址:https://www.cnblogs.com/JChen666/p/3575273.html
Copyright © 2011-2022 走看看