JavaScript 常见的5种设计模式

本文是自己学习 JavaScript 设计模式的笔记,整理了 JavaScript 常见的五种设计模式,并总结了相应的案例代码。

1. 装饰者模式

装饰者模式是指,在不改变对象自身代码的前提下,新增功能的模式。

如下代码所示,创建3个飞机对象。plane可以发射普通子弹plane2不仅可以发射普通子弹,还可以发射导弹plane3不仅可以发射普通子弹导弹,还可以发射炮弹

创建构造函数Plane2时,不改变plane的功能,只增加功能,将Plane的实例挂载到自身属性上,并在fire方法下,调用Plane的方法,并增加一个功能:发射导弹。Plane3同理。

// 飞机大战
// 普通子弹  导弹   炮弹

// 发射普通子弹的飞机
function Plane() {}
Plane.prototype.fire = function () {
    console.log('普通子弹');
};

// 可发射导弹的飞机
function Plane2(plane) {
    this.plane = plane;
}
Plane2.prototype.fire = function () {
    this.plane.fire();
    console.log('导弹');
};

// 可发射炮弹的飞机
function Plane3(plane) {
    this.plane = plane;
}
Plane3.prototype.fire = function () {
    this.plane.fire();
    console.log('炮弹');
};

const plane = new Plane();
const plane2 = new Plane2(plane); // 在plane上增加发射导弹
const plane3 = new Plane3(plane2); // 在plane2上增加发射炮弹

plane.fire();
// 普通子弹

plane2.fire();
// 普通子弹
// 导弹

plane3.fire();
// 普通子弹
// 导弹
// 炮弹

2. 策略模式

策略模式主要解决的是if-else逻辑复杂而不可维护的情况。

如下代码所示,模拟一个公司发奖金的场景。base代表基础金额,grade代表等级。gradesabcd五种等级,分别发放的奖金为54321倍的基础金额。

定义一个策略对象strategy,分别有对应5种等级的函数,返回相应的金额。在计算奖金函数getBonus中,只需传入相应的basegrade即可。如果要更改逻辑,只需在strategy对象中更改策略,无需更改计算奖金函数的代码逻辑。

const strategy = {
    s(base) {
        return base * 5;
    },
    a(base) {
        return base * 4;
    },
    b(base) {
        return base * 3;
    },
    c(base) {
        return base * 2;
    },
    d(base) {
        return base * 1;
    },
};

const getBonus = (base, grade) => strategy[grade](base);

const res1 = getBonus(1000, 's'); // 5000
const res2 = getBonus(1500, 'a'); // 6000

3. 代理模式

代理模式主要用于转发请求。

如下代码,模拟发送邮件的过程,但是发送者不直接将邮件送给接收者,而是将邮件交给邮递员邮递员将邮件交给接收者

// 创建邮件对象
function Mail(sender, content) {
    this.sender = sender; // 发送者
    this.content = content; // 邮件内容
}

// 发布者
const sender = {
    // target:实际交给谁
    // receiver:最终的接收者
    // mail:发送的邮件
    send(target, receiver, mail) {
        target.send(receiver, mail);
    },
};

// 邮递员
const postMan = {
    // receiver:最终的接收者
    // mail:发送的邮件
    send(receiver, mail) {
        receiver.receive(mail);
    },
};

// 接收者
const receiver = {
    // mail:接收到的邮件
    receive(mail) {
        console.log(`Receive <${mail.content}> from ${mail.sender}`);
    },
};

const mail = new Mail('Jack', 'Hello');

// 邮件交给postMan,最终送给receiver,邮件是mail
sender.send(postMan, receiver, mail);
// Receive <Hello> from Jack

4. 发布订阅模式

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

实际上,一个普通的事件绑定,也是一种发布订阅模式。如下代码所示,发布者为用户,监听者为绑定的事件。

document.addEventListener('click', e => {
    console.log(e);
});

如下代码所示,模拟明星发布消息,粉丝收到消息的场景。在这个场景中,明星star发布消息后,每个粉丝都能收到消息,并作出不同的反应。

发布者star监听者为每个粉丝。

class Star {
    constructor() {
        // 粉丝队列
        this.followers = [];
    }
    follow(obj) {
        // 将obj加入粉丝队列
        this.followers.push(obj);
    }
    publish() {
        // 发布消息,通知粉丝
        this.followers.forEach(item => {
            item.fn(item.name);
        });
    }
}

const star = new Star();

// 三个用户关注star
star.follow({
    name: 'Jack',
    fn(name) {
        console.log(`${name}看到消息!`);
    },
});
star.follow({
    name: 'Jone',
    fn(name) {
        console.log(`${name}看到消息,并点赞!`);
    },
});
star.follow({
    name: 'Tom',
    fn(name) {
        console.log(`${name}看到消息,并评论!`);
    },
});

// star发布消息
star.publish();
// Jack看到消息!
// Jone看到消息,并点赞!
// Tom看到消息,并评论!

5. 迭代器模式

迭代器模式描述了一个方案,即可以把有些结构称为可迭代对象,因为它们实现了正式的Iterable接口,而且可以通过迭代器Iterator消费。

简单来说,遍历可迭代对象,就是一种迭代器模式。

如下代码所示,编写了一个倒序遍历数组的函数reverseEach,实现倒序遍历。

const nums = [1, 2, 3, 4, 5];

const reverseEach = (arr, callback) => {
    if (!Array.isArray(arr)) throw Error(`请传入数组!`);
    const len = arr.length;
    for (let i = len - 1; i >= 0; i--) {
        callback.call(arr[i], arr[i], i);
    }
};

reverseEach(nums, (num, index) => {
    console.log(num, index);
});
// 5 4
// 4 3
// 3 2
// 2 1
// 1 0
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火星飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值