zoukankan      html  css  js  c++  java
  • 《JavaScript设计模式与开发实践》整理

    最近在研读一本书《JavaScript设计模式与开发实践》,进阶用的。

    一、高阶函数

    高阶函数是指至少满足下列条件之一的函数。

    1. 函数可以作为参数被传递

    2. 函数可以作为返回值输出

    1)高阶函数实现AOP

    AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。

    把这些功能抽离出来之后,再通过“动态织入”的方式掺入业务逻辑模块中。

    这样做的好处首先是可以保持业务逻辑模块的纯净和高内聚性,其次是可以很方便地复用日志统计等功能模块。

    在 JavaScript 中实现 AOP,都是指把一个函数“动态织入”到另外一个函数之中,查看demo

    Function.prototype.before = function( beforefn ){
        var __self = this;    // 保存原函数的引用
        return function(){    // 返回包含了原函数和新函数的"代理"函数
            beforefn.apply( this, arguments );     // 执行新函数,修正 this
            return __self.apply( this, arguments );    // 执行原函数
        }
    };
    Function.prototype.after = function( afterfn ){
        var __self = this;
        return function(){
            var ret = __self.apply( this, arguments );
            afterfn.apply( this, arguments ); 
            return ret;
        }
    };
    
    var func = function(){
        console.log( 2 );
    };
    func = func.before(function(){
        console.log( 1 );
    }).after(function(){
        console.log( 3 ); 
    });
    func();//1 2 3

    2)currying

    函数柯里化(function currying)又称部分求值

    一个 currying 的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。

    待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。简单点说就是返回一个函数。demo查看

    var cost = (function() {
      var args = [];
    
      return function() {
        if (arguments.length === 0) {
          var money = 0;
          for (var i = 0, l = args.length; i < l; i++) {
            money += args[i];
          }
          return money;
        } else {
          [].push.apply(args, arguments);
        }
      }
    })();
    
    cost(100); // 未真正求值
    cost(200); // 未真正求值
    cost(300); // 未真正求值
    console.log(cost()); // 求值并输出:600

    二、设计模式

    1)单例模式

    定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    单例模式的核心是确保只有一个实例,并提供全局访问。

    惰性单例。

    demo代码

    2)策略模式

    定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

    这句话如果说得更详细一点,就是:定义一系列的算法,把它们各自封装成策略类,算法被封装在策略类内部的方法里。在客户对 Context 发起请求的时候,Context 总是把请求委托给这些策略对象中间的某一个进行计算。

    计算奖金、缓动动画、表单校验。

    demo代码

    3)代理模式

    代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

    代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理之后,再把请求转交给本体对象。

    保护代理和虚拟代理,虚拟代理实现图片预加,缓存代理,用高阶函数动态创建代理。

    demo代码

    4)迭代器模式

    迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。

    内部迭代器和外部迭代器,

    demo代码

    5)发布—订阅模式

    发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

    DOM事件, 自定义事件,通用实现。

    demo代码

    6)命令模式

    命令模式中的命令(command)指的是一个执行某些特定事情的指令。

    命令模式最常见的应用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。

    此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。

    菜单程序,撤消命令,命令队列。

    demo代码

    7)组合模式

    组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。

    除了用来表示树形结构之外,组合模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性。

    宏命令,扫描文件夹。

    demo代码

    8)模板方法模式

    模板方法模式是一种只需使用继承就可以实现的非常简单的模式。

    模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。

    在模板方法模式中,子类实现中的相同部分被上移到父类中,而将不同的部分留待子类来实现。这也很好地体现了泛化的思想。

    Coffee or Tea,钩子方法,好莱坞原则。

    demo代码

    9)享元模式

    享元(flyweight)模式是一种用于性能优化的模式,“fly”在这里是苍蝇的意思,意为蝇量级。

    享元模式的核心是运用共享技术来有效支持大量细粒度的对象。

    通用结构,通用对象池。

    demo代码

    10)职责链模式

    职责链模式的定义是:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

    职责链的实现,用AOP实现职责链

    demo代码

    11)中介者模式

    中介者模式的作用就是解除对象与对象之间的紧耦合关系。增加一个中介者对象后,所有的相关对象都通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。

    泡泡堂。

    demo代码

    12)装饰者模式

    装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象。

    飞机大战,装饰函数,用AOP 装饰函数 。

    demo代码

    13)状态模式

    允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

    第一部分的意思是将状态封装成独立的类,并将请求委托给当前的状态对象,当对象的内部状态改变时,会带来不同的行为变化。

    第二部分是从客户的角度来看,我们使用的对象,在不同的状态下具有截然不同的行为,这个对象看起来是从不同的类中实例化而来的,实际上这是使用了委托的效果。

    通用结构,文件上传,JavaScript 版本的状态机。

    demo代码

    14)适配器模式

    适配器模式主要用来解决两个已有接口之间不匹配的问题,它不考虑这些接口是怎样实现的,也不考虑它们将来可能会如何演化。

    适配器模式不需要改变已有的接口,就能够使它们协同作用。

  • 相关阅读:
    克如斯卡尔 P1546
    真正的spfa
    第四课 最小生成树 要点
    关于vscode中nullptr未定义
    cmake学习笔记
    python学习笔记
    (BFS 图的遍历) 2906. kotori和迷宫
    (图论基础题) leetcode 997. Find the Town Judge
    (BFS DFS 并查集) leetcode 547. Friend Circles
    (BFS DFS 图的遍历) leetcode 841. Keys and Rooms
  • 原文地址:https://www.cnblogs.com/strick/p/5895969.html
Copyright © 2011-2022 走看看