这是我参与更文挑战的第11天,活动详情查看: 更文挑战
写在前面
这几天在学一下设计模式,虽然说前端是写页面,做切图仔(调侃一下),但是也有很大部分时候是写逻辑的,下面我把常用的设计模式总结一下,正所谓工欲善其事必先利其器, 如果我们能在代码中使用到一些设计模式,对我们代码的优化还是有很大帮助的。
设计模式
单体模式
单体模式,就是指一个类内部只实例化一个实例,不管你使用这个类创建几个实例,这几个实例返回的都是同一个实例。
class singleMode {
constructor(name) {
this.name = name
}
getName () {
return this.name
}
getInstance () {
return this
}
}
createSingleMode = (function () {
let singleModeInstance
return function (name) {
if (!singleModeInstance) singleModeInstance = new singleMode(name)
return singleModeInstance
}
})()
const singleMode1 = new createSingleMode('答案cp3')
const singleMode2 = new createSingleMode('答案cp3')
console.log(singleMode1 === singleMode2) // true
console.log(singleMode1.getInstance() === singleMode2.getInstance()) // true
console.log(singleMode1.getName()) // 答案cp3
console.log(singleMode2.getName()) // 答案cp3
复制代码
从以上代码可以看到,如果创建过实例,则不需再创建,直接返回,所以返回的实例是相等的,是同一个实例。
工厂模式
工厂模式,在内部将创建具体对象的过程操作单独封装,不对外暴露出来。
function Factory (name) {
const obj = {}
obj.name = name
obj.getName = function () {
return this.name
}
return obj
}
const factory1 = new Factory('答案')
const factory2 = new Factory('cp3')
console.log(factory1.getName()) // 答案
console.log(factory2.getName()) // cp3
复制代码
上面代码中obj就是在函数Factory内部创建,并且赋值方法,属性等。
策略模式
定义好需要的策略,然后根据传入的策略名去执行对应的策略。
比如你想开通会员,有青铜会员,白银会员,黄金会员,开通会员后对应的商品折扣是不同的,这时候就可以用上策略模式。
const memberType = {
copper: function (price) {
return price * 0.9
},
silver: function (price) {
return price * 0.7
},
gold: function (price) {
return price * 0.5
}
}
memberType['copper'](100) // 打折后 90
memberType['silver'](100) // 打折后 70
memberType['gold'](100) // 打折后 50
复制代码
根据身份定好折扣,传入身份和价格,就知道打折后是多少,这种策略模式可读性强,维护性好,不需要写多余的if和else。
代理模式
给目标对象设置一个代理,不直接暴露目标对象。
// 为这个target设置一个代理
class Target {
constructor (name) {
this.name = name
}
getName () {
return this.name
}
}
// 代理
class ProxyTarget {
constructor (name) {
this.target = new Target(name)
}
getName () {
return this.target.getName()
}
}
const proxy = new ProxyTarget('答案cp3')
proxy.getName() // 答案cp3
复制代码
以上就是给Target对象设置一个ProxyTarget,外界不能直接访问到Target
装饰器模式
装饰器模式就是在不改变对象自身的基础上,给对象添加新方法,同时旧方法也还在
class Circle {
draw() {
console.log('先画一个圆形')
}
}
// 装饰器
class DecoratorMode {
constructor(circle) {
this.circle = circle
}
draw() {
this.circle.draw()
this.setRedBg(this.circle)
}
setRedBg(circle) {
console.log('再设置红色背景')
}
}
let circle = new Circle()
let decorator = new DecoratorMode(circle); // 把circle实例传入
decorator.draw(); // 先画一个圆形,再设置红色背景
复制代码
上面代码中,装饰器模式在对象的draw方法额外加上了setRedBg方法
发布-订阅模式
发布-订阅模式其实是1对N的关系,订阅者先把自己把事件订阅到调度台,然后发布者发布该事件到调度台,调度台调用该事件对应的函数。 vue2.0内部的Vue watch等就是利用这个模式
// 构造函数,调度台
function Publish () {
this.subObj = {}
}
// 订阅者
Publish.prototype.on = function(name, fn) {
if(this.subObj[name]) {
this.subObj[name].push(fn)
} else this.subObj[name] = [fn]
}
// 发布者
Publish.prototype.emit = function (name, data) {
if (this.subObj[name]) {
for(let i = 0; i < this.subObj[name].length; i++) {
this.subObj[name][i](data)
}
}
}
Publish.prototype.off = function (name, fn) {
if (this.subObj[name]) {
if(fn) {
for(let i = 0; i < this.subObj[name].length; i++) {
if(this.subObj[name][i] === fn) {
this.subObj[name].splice(i,1)
}
}
} else {
delete this.subObj[name]
}
}
}
const a = new Publish()
const fn1 = () => {
console.log('fn1')
}
const fn2 = () => {
console.log('fn2')
}
a.on('aaa', fn1) // 订阅 fn1
a.on('aaa', fn2) // 订阅 fn2
a.emit('aaa') // 输出 fn1 和 fn2
a.off('aaa', fn1) // 取消订阅
a.emit('aaa') // 只输出 fn2
复制代码
总结
以上就是最近学到的几种常用的设计模式的总结,希望对你们能有帮助。一起加油~
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)