关于javascript:几种常用设计模式的简单示例

3次阅读

共计 3214 个字符,预计需要花费 9 分钟才能阅读完成。

前言

模式是在某一背景下某个问题的一种解决方案。

设计模式(Design pattern)是一套被重复应用、少数人通晓的、通过分类编目标、代码设计教训的总结。

为了保障代码的可靠性、进步代码的复用率、使代码更容易被保护和浏览,咱们须要理解并正当应用设计模式。

日常开发中,一些特定的场景下你的解决办法可能并不是很现实,往往这时借助一些设计模式能够让你优雅而高效的实现这些逻辑,上面就介绍一些尽管不是最全的但肯定是最罕用的设计模式。

单例模式:

定义: 一个类只返回一个实例,一旦创立再次调用就间接返回。

应用场景: 比方自定义弹窗,无论你程序中多少调用,都只应创立一个弹窗对象。

class CreateUser {constructor(name) {
        this.name = name;
        this.getName();}
    getName() {return this.name;}
};

const ProxyMode = (() => {
    let instance = null;
    return (name) => {if(!instance) {instance = new CreateUser(name);
        }
        return instance;
    }
})();

let a = ProxyMode('vn');
let b = ProxyMode('lb');

console.log(a, b);   // vn  vn    单例模式只会创立一次实例 

策略模式:

定义: 定义一个策略类只专一与各办法算法实现,定义一个接口调用这些办法。

特点 :代码优雅,可读性高。

// 策略类
const levelObj = {
    "A": money => money * 4,
    "B": money => money * 3,
    "C": money => money * 2
}

// 环境类  封装调用接口
const getMoney = (level, money) => levelObj[level](money);

console.log(getMoney('A', 200))   // 800

代理模式:

定义: 为一个对象提供一个代用品或占位符,以便管制对它的拜访。

应用场景: 比方图片懒加载,先缓存动静 loading,必要时传入 src。

const imgFunc = (() => {let imgNode = document.createElement('img');
    document.body.appendChild(imgNode);
    return {setSrc: (src) => {imgNode.src = src;}
    }
})();

const ProxyImg = (() => {let img = new Image();
    img.onload = () => {let node = document.getElementsByTagName('img')
        imgFunc.setSrc(img.src);
    }
    return {setSrc: (src) => {imgFunc.setSrc('../C3photo/jacky/1.jpg');
            img.src = src;
        }
    }
})();

ProxyImg.setSrc('../C3photo/jacky/2.jpg');

装璜者模式:

定义: 装璜者模式可能在不扭转对象本身的根底上,在运行程序期间给对象动静地增加职责。

应用场景: 相似于拦截器,增加对象的前置和后置事件等。

Function.prototype.before = function(beforefn) {
    let _self = this;                          
    return function () {beforefn.apply(this, arguments);
        return _self.apply(this, arguments);
    }
}
Function.prototype.after = function(afterfn) {
    let _self = this;
    return function(){let ret = _self.apply(this, arguments);
        afterfn.apply(this, arguments);
        return ret;
    }
}
let func = function() {console.log('2');
}
//func1 和 func3 为挂载函数
let func1 = function() {console.log('1');
}
let func3 = function() {console.log('3');
}

func = func.before(func1).after(func3);
func();   // 1  2  3

公布订阅模式:

定义: 订阅者(Subscriber)把本人想订阅的事件注册(Subscribe)到调度核心(Event Channel),当发布者(Publisher)公布该事件(Publish Event)到调度核心,也就是该事件触发时,由调度核心对立调度(Fire Event)订阅者注册到调度核心的解决代码。

应用场景: 微信公众号的订阅

let eventEmitter = {list: {}, 

    on(event, fn) {
        // 订阅
        let _this = this;
        _this.list[event] = _this.list[event] || [];
        _this.list[event].push(fn);
        return _this;
    },

    emit() {
        // 公布
        let _this = this;
        let event = [].shift.call(arguments),
            fns = _this.list[event];
        if (fns && fns.length) {fns.forEach((fn) => fn.apply(_this, arguments));
        }
        return _this;
    },

    off(event, fn) {
        // 勾销订阅
        let _this = this;
        let fns = _this.list[event];
        if (!fns) return false;
        if (!fn) {fns.length = 0;} else {for (let i = 0; i < fns.length; i++) {if (fns[i] === fn || fns[i].fn === fn) {fns.splice(i, 1);
                    break;
                }
            }
        }
    }
};

const user1 = (content) => {console.log("用户 1 订阅了:", content);
};

const user2 = (content) => {console.log("用户 2 订阅了:", content);
};

const user3 = (content) => {console.log("用户 3 订阅了:", content);
};

// 订阅
eventEmitter.on("article1", user1);
eventEmitter.on("article1", user2);
eventEmitter.on("article2", user3);

eventEmitter.emit("article1", "Javascript 公布 - 订阅模式");
eventEmitter.emit("article2", "Javascript 观察者模式");

eventEmitter.off("article1", user1);
eventEmitter.emit("article1", "Javascript 公布 - 订阅模式");

// 用户 1 订阅了: Javascript 公布 - 订阅模式
// 用户 2 订阅了: Javascript 公布 - 订阅模式
// 用户 3 订阅了: Javascript 观察者模式
// 用户 2 订阅了: Javascript 公布 - 订阅模式

总结

学习设计模式不仅能够使咱们用好这些胜利的设计模式,更重要的是能够使咱们深刻了解面向对象的设计思维。

~

~ 本文完,感激浏览!

~

学习乏味的常识,结识乏味的敌人,塑造乏味的灵魂!

大家好,我是〖编程三昧〗的作者 隐逸王 ,我的公众号是『编程三昧』,欢送关注,心愿大家多多指教!

你来,怀揣冀望,我有墨香相迎!你归,无论得失,唯以余韵相赠!

常识与技能并重,内力和外功兼修,实践和实际两手都要抓、两手都要硬!

正文完
 0