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();
        ...
    }
  • 相关阅读:
    基础练习 龟兔赛跑预测
    SQL查询
    通讯录管理系统
    信号分解
    开源框架 openFrameworks
    开博了
    AES加密原理和AOE工程实践
    一文读懂AOE到底是什么!
    AoE 搭档 TensorFlow Lite ,让终端侧 AI 开发变得更加简单。
    AOE工程实践-银行卡OCR里的图像处理
  • 原文地址:https://www.cnblogs.com/JChen666/p/3575273.html
Copyright © 2011-2022 走看看