博客列表 >几种常用设计模式的简单示例

几种常用设计模式的简单示例

编程三昧
编程三昧原创
2021年08月21日 23:22:05709浏览

前言

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

设计模式(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 发布-订阅模式

总结

学习设计模式不仅可以使我们用好这些成功的设计模式,更重要的是可以使我们深入理解面向对象的设计思想。

~

~本文完,感谢阅读!


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议