• 设计模式


    Observer Pattern(观察者模式)

    Observer Pattern 其实很常遇到,许多API 的设计上都用了Observer Pattern,最简单的例子就是DOM 物件的事件监听:

    function clickHandler(event) {
        console.log('user click!');
    }
    
    document.body.addEventListener('click', clickHandler)

    观察者模式:我们可以对某件事注册监听,并在事件发生时,自动执行我们注册的监听者(listener)。

    Es5版本:

    function Producer() {
        
        // 这个 if 只是避免使用者不小心把 Producer 当做函数调用
        if(!(this instanceof Producer)) {
          throw new Error('请用 new Producer()!');
        }
        
        this.listeners = [];
    }
    
    // 加入监听的方法
    Producer.prototype.addListener = function(listener) {
        if(typeof listener === 'function') {
            this.listeners.push(listener)
        } else {
            throw new Error('listener 必须是 function')
        }
    }
    
    // 移除监听的方法
    Producer.prototype.removeListener = function(listener) {
        this.listeners.splice(this.listeners.indexOf(listener), 1)
    }
    
    // 发送通知的方法
    Producer.prototype.notify = function(message) {
        this.listeners.forEach(listener => {
            listener(message);
        })
    }

    es6 版本

    class Producer {
        constructor() {
            this.listeners = [];
        }
        addListener(listener) {
            if(typeof listener === 'function') {
                this.listeners.push(listener)
            } else {
                throw new Error('listener 必须是 function')
            }
        }
        removeListener(listener) {
            this.listeners.splice(this.listeners.indexOf(listener), 1)
        }
        notify(message) {
            this.listeners.forEach(listener => {
                listener(message);
            })
        }
    }

    调用例子:

    var egghead = new Producer(); 
    
    function listener1(message) {
        console.log(message + 'from listener1');
    }
    
    function listener2(message) {
        console.log(message + 'from listener2');
    }
    
    egghead.addListener(listener1);egghead.addListener(listener2);
    
    egghead.notify('A new course!!') 

    /**

    输出:

    a new course!! from listener1
    a new course!! from listener2

    **/

    Iterator Pattern (迭代器模式)

    var arr = [1, 2, 3];
    
    var iterator = arr[Symbol.iterator]();
    
    iterator.next();
    // { value: 1, done: false }
    iterator.next();
    // { value: 2, done: false }
    iterator.next();
    // { value: 3, done: false }
    iterator.next();
    // { value: undefined, done: true }

    简单实现:

    es5:
    
    function IteratorFromArray(arr) {
        if(!(this instanceof IteratorFromArray)) {
            throw new Error('请用 new IteratorFromArray()!');
        }
        this._array = arr;
        this._cursor = 0;    
    }
    
    IteratorFromArray.prototype.next = function() {
        return this._cursor < this._array.length ?
            { value: this._array[this._cursor++], done: false } :
            { done: true };
    }
    
    es6:
    
    class IteratorFromArray {
        constructor(arr) {
            this._array = arr;
            this._cursor = 0;
        }
      
        next() {
            return this._cursor < this._array.length ?
            { value: this._array[this._cursor++], done: false } :
            { done: true };
        }
    }

    优势

    1. Iterator的特性可以拿来做延迟运算(Lazy evaluation),让我们能用它来处理大数组。
    2. 第二因为iterator 本身是序列,所以可以第调用方法像map, filter... 等!

    延迟运算(Lazy evaluation)

     

    function* getNumbers(words) {
            for (let word of words) {
                if (/^[0-9]+$/.test(word)) {
                    yield parseInt(word, 10);
                }
            }
    }
        
    const iterator = getNumbers('30 天精通 RxJS (04)');
        
    iterator.next();
    // { value: 3, done: false }
    iterator.next();
    // { value: 0, done: false }
    iterator.next();
    // { value: 0, done: false }
    iterator.next();
    // { value: 4, done: false }
    iterator.next();
    // { value: undefined, done: true }

    把一个字串丢进getNumbersh函数时,并没有马上运算出字串中的所有数字,必须等到我们执行next()时,才会真的做运算,这就是所谓的延迟运算(evaluation strategy)

    选自

    https://segmentfault.com/a/1190000013141856

  • 相关阅读:
    Java's Volatile Keyword
    reflection
    Spring
    Stack
    Set
    Vector & ArrayList
    CreateFileDemo
    session原理
    multithreadingDemo
    REST风格
  • 原文地址:https://www.cnblogs.com/fengnovo/p/8872656.html
Copyright © 2020-2023  润新知