让我了解了设计模式

544 阅读4分钟

接下来让我们直接上干货

一、单例模式 (重要)

单例模式是我们前端日常接触到比较广泛的一种设计模式。例如在我们设置一些事件触发弹窗时,如果我们多次触发这个事件,是不是每次都会创建一个新的弹窗呢?这是不是会比较损耗性能呢? 答案当然是肯定的。

单例模式的核心思想就是确保一个类只对应一个实例。每当我们调用构造函数的时候,返回指向同一个对象的指针。换一种说法就是我们只在第一次调用构造函数的时候创建对象,之后调用返回第一次创建的对象即可。 这样是不是就可以解决上边的那样的问题呢? 这当然也是肯定的。

var Singleton = function (name) {
   this.name = name;
   this.instance = null;
}

Singleton.prototype.getName = function () {
   console.log(this.name);
}

Singleton.getInstance = function (name) {
   if (!this.instance) {
       this.instance = new Singleton(name);
   }
   return this.instance;
}

var s1 = Singleton.getInstance('s1');
var s2 = Singleton.getInstance('s2');

console.log(s1, s2, s1 === s2)
//Singleton { name: 's1', instance: null }
//Singleton { name: 's1', instance: null }
//true


// 下面书写一个构造器
var ProxySingleton = (function () {
   var _instance = null;
   return function (Func) {
       if (!_instance) {
           _instance = new Func();
       }
       return _instance;
   }
})()

function Func() {
   this.name = '张三'
}

var p1 = ProxySingleton(Func);//Func { name: '张三' }
var p2 = ProxySingleton(Func);//Func { name: '张三' }

console.log(p1, p2, p1 === p2)//true

二、观察者模式(重要)pub-sub

观察者模式又叫做发布订阅者模式。它定义对象间的一种一对多的依赖关系,每当一个对象的状态发生改变时侯,所有依赖它的对象都能得到通知和更新。观察者模式提供一个订阅模型,其中对象订阅事件并在发生时候得到通知,这种模式是事件驱动的编程基石,有利于良好的面向对象设计。

const map = {};
function Listen(key, fn) {
    if (!map[key]) {
        map[key] = [];
    }
    map[key].push(fn)
}
function trigger(key, data) {
    map[key].forEach(item => item(data));
}

Listen('event1', function () { console.log('this is listener 1') });
Listen('event2', function () { console.log('this is listener 2') });
Listen('event2', function () { console.log('this is listener 2-1') });

trigger('event1') //this is listener 1
trigger('event2') //this is listener 2   this is listener 2-1

三、代理们模式

代理模式视为一个对象提供一个代用品或者占位符,以便来控制对他的访问。 代理模式是一种十分有意义的模式,在生活钟可以找到很多代理模式的场景,比如要邀请某个公司老板参加活动,那我们就得联系他的秘书,秘书会将相关事宜转达给老板。 代理模式的关键是,当我们调用一个外部的库时候,需要传递一个对象或者方法,我们不方便直接访问,这时候就可以将代理对象代替变量或者方法,将代理对象传过去,做出一些处理。

var ProxySingleton = (function(){
    var _instance = new Map();
    return function(){
        if(!_instance.get(Func)){
            _instance.set(Func,new Func());
        }
        return _instance.get(Func);
    }
})()

function A(){ this.name = Math.random()};
function B(){ this.name = Math.random()};

var a = new ProxySingleton(A);
var b = new ProxySingleton(B);
console.log(a,b,a===b);

四、迭代器模式

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

var Iterator = function (obj) {
    var current = 0;
    var next = function () {
        current += 1;
    }
    var isFinished = function () {
        return !!(current >= obj.length);
    }
    var getCurrentItem = function () {
        return obj[current];
    }
    var reset = function () {
        current = 0;
    }
    return {
        next,
        isFinished,
        getCurrentItem,
        reset
    }
}

var array1 = [1, 2, 3, 4, 5];
var array2 = [1, 2, 3, 4, 5];
var array3 = [2, 3, 4, 5, 6];

function compare(Iterator1, Iterator2) {
    while (!Iterator1.isFinished() && !Iterator2.isFinished()) {
        if (Iterator1.getCurrentItem() !== Iterator2.getCurrentItem()) {
            Iterator1.reset();
            Iterator2.reset();
            return false;
        }
        Iterator1.next();
        Iterator2.next();
    }
    Iterator1.reset();
    Iterator2.reset();
    return true;
}

var arrayLike1 = { 0: 0, 1: 1, 2: 2, length: 3 };
var array4 = [0, 1, 2];




var array1Iterator = Iterator(array1);
var array2Iterator = Iterator(array2);
var array3Iterator = Iterator(array3);

var array4Iterator = Iterator(arrayLike1);
var array5Iterator = Iterator(array4);
var array6Iterator = Iterator(array3);

console.log(compare(array1Iterator, array2Iterator));//true
console.log(compare(array2Iterator, array3Iterator));//false

console.log(compare(array4Iterator, array5Iterator));//true
console.log(compare(array5Iterator, array6Iterator));//false

五、职责链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象连接成一条链,并沿着这条链来处理请求,直到有一个对象处理它为止。

const judgeA = () => false;
const judgeB = () => true;
const runA = (args) => console.log('A', args);
const runB = (args) => console.log('B', args);

function useA(obj) {
    console.log('使用A')
    if (judgeA()) {
        return runA(obj);
    }
    return 'next';
}

function useB(obj) {
    console.log('使用B')
    if (judgeB()) {
        return runB(obj);
    }
    return 'next';
}

function createChain() {
    Function.prototype.chain = function (nextFunc) {
        var self = this;
        return function () {
            var result = self.apply(this, arguments);
            if (result === 'next') {
                return nextFunc.apply(this, arguments);
            }
            return result;
        }
    }
}

createChain();

var upload = useA.chain(useB);

upload({ info: 'info' })
// 使用A
// 使用B
// B { info: 'info' }

六、策略模式

很多时候,我们实现一个功能可能可以使用多种方式进行,同时我们可能需要不同的方式进行切换,对我们的策略模式来说吗,我们需要定定义一系列算法,能够让我们在这种类似的情境中进行随时。

var strategies = {
    'A' :function (salary){
        return salary * 4;
    },
    'B':function(){
        return salary * 3;
    },
    'C':function(){
        return salary * 2;
    }
}

var calculateBonus = function (level,salary){
    return strategies[level][salary];
}

以上就是我为大家带来的内容,希望可以帮到大家!


希望大家可以不骄不躁、每天都要进步!