zoukankan      html  css  js  c++  java
  • 《JavaScript设计模式》笔记之第一、二章:富有表现力的JavaScript 和 接口


    第一章

    创建一个类

    方法一:
         var Anim = function() {
              ...
         };
         Anim.prototype.start = function() {
              ...
         };
         Anim.prototype.stop = function() {
              ...
         };
    方法二:
         var Anim = function() {
              ...
         };
         Anim.prototype = {
              start: function() {
                   ...
              },
              stop: function() {
                   ...
              }
         };
    方法三:
         Function.prototype.method =  function(name, fn) {
              this.prototype[name] = fn;
         };
         var Anim = function() {
              ...
         };
         Anim.method('start', function() {
              ...
         });
         Anim.method('stop', function() {
              ...
         });
    方法四(在方法三上增加链式调用):
         只需要在method方法上添加return this;
         Function.prototype.method =  function(name, fn) {
              this.prototype[name] = fn;
              return this;
         };

    第二章
    接口模仿
    方法一:用注释描述接口
    /*
         interface Composite {
              function add(child);
              function remove(child);
         }
    */
     
    var CompositeForm = function(id, method, action) { //inplements Composite
         ...
    };
     
    //继承Composite接口
     
    CompositeForm.prototype.add = function(child) {
         ...
    };
    CompositeForm.prototype.remove = function(child) {
         ...
    };
     
    缺点:主要利用注释来口头约束,要靠程序员自觉遵守
    优点:不需要额外的类或函数,简单方便
     

    方法二:用属性检查模仿接口
    说明:在方法一中增加代码,主要是在需要继承某些接口的类中添加一个属性用于,告诉别人它有没有继承某些类,此外,再增加一个检查执行的函数,就可以方便的检查某个类是否继承了某些接口
    缺点: 如果程序员只是声明了自己有实现那个接口,但是没有实际实现,就会造成问题
    优点: 如果程序员正真按照约定,没在代码上说谎,那么就能有效的检测是否实现了接口
    例子:
    /*
    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 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;
     
    // 使用例子
    function addForm(formInstance) {
         if(!implements(formInstance, 'Composite', 'FormItem')) {
              throw new Error("没有实现某些接口");
         }
         ...
    }

    方法三:鸭式辩型模仿接口
    例子:
    // 接口列表(个人理解:使用neInterface只是让别人知道这是一个接口定义,简单点可以直接用一个数组来代替)
    var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
    var FormItem = new Interface('FormItem', ['save']);
     
    //使用的时候通过一个定义好的函数ensureImplements来检查是否实现了接口
    ensureImplements(formInstance, Composite, FormItem);
     
    说明: 这种方法的思想就是检测对象是否有与接口同名的方法
     

    方法四:结合方法一和方法三的方法
    例子:
    // 接口列表
    var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
    var FormItem = new Interface('FormItem', ['save']);
     
    // 要实现上述接口的类
    var CompositeForm = function(id, method, action) { 
         ... // 实现Composit接口和FormItem接口
    };
     
    function addForm(formInstance) {
         Interface.ensureImplements(formInstance, Composite, FormItem);
    }
     

    Interface 类
    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]);
         }
    };
     
    // 验证实现的方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Interface.ensureImplements = function(object) {
        if(arguments.length < 2) {
            throw new Error("Interface.ensureImplements函数接收到的参数个数:"+arguments.length+",但是函数需要的参数个数为:2");
        }
     
        for(var i = 1, len = arguments.length; i < len; i++) {
            var interface = arguments[i];
            if(interface.constructor !== Interface) {
                throw new Error("Interface.ensureImplements函数需要参数2以及后面的参数为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("Interface.ensureImplements函数: 实例没有实现以下方法:"+interface.name);
                }
            }
        }
    };

    综合例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    <html>
     
    <body>
        <script>
            //Interface 类
            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.ensureImplements = function (object) {
                if (arguments.length < 2) {
                    throw new Error("Interface.ensureImplements函数接收到的参数个数:" + arguments.length + ",但是函数需要的参数个数为:2");
                }
     
                for (var i = 1, len = arguments.length; i < len; i++) {
                    var interface = arguments[i];
                    if (interface.constructor !== Interface) {
                        throw new Error("Interface.ensureImplements函数需要参数2以及后面的参数为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("Interface.ensureImplements函数: 实例没有实现以下方法:" + interface.name);
                        }
                    }
                }
            };
             
            //定义了一个接口,接口需要有run方法和jump方法
            var Animal = new Interface('Animal',['run''jump']);
             
            //实现Animal接口的Cat类
            function Cat() {}
            Cat.prototype.run = function() {};
            Cat.prototype.jump = function() {};
             
            //实现Animal接口的Dog类
            function Dog() {}
            Dog.prototype.run = function() {};
            Dog.prototype.jump = function() {};
             
            //没有实现Animal的Car类
            function Car() {}
            Car.prototype.drive = function() {};
             
            //有一只猫叫cat,有一只狗叫dog,有一部车叫car
            var cat = new Cat();
            var dog = new Dog();
            var car = new Car();
             
            //假设一个人叫啊Mark,然后他很喜欢收养动物,今天他又来收养动物了。
            var Mark = {
                adopt: function(animal) {
                    Interface.ensureImplements(animal, Animal);
                    console.log("收养一只"+animal.constructor.name+"成功");
                }
            };
            Mark.adopt(cat);
            Mark.adopt(dog);
            Mark.adopt(car);
             
        </script>
    </body>
     
    </html>
     
     
     
     
     
     
     
     
     
     
     
            
  • 相关阅读:
    DHCP服务器搭建
    Nginx Web服务器
    ansible批量管理工具
    同网段存活IP公钥分发脚本
    inotify事件监控工具
    搭建云yum仓库和本地定时yum仓库
    NFS网络文件共享系统
    shell 脚本的讲解 与应用
    awk 命令精讲
    ACL权限控制 及特殊权限
  • 原文地址:https://www.cnblogs.com/oadaM92/p/4342614.html
Copyright © 2011-2022 走看看