设计模式
最后更新于:2022-04-02 03:27:43
[TOC]
## 适配器
可用于对新老数据的转换兼容
```
const arr = ['Javascript', 'book', '前端编程语言', '8月1日']
function arr2objAdapter(arr) { // 转化成我们需要的数据结构
return {
name: arr[0],
type: arr[1],
title: arr[2],
time: arr[3]
}
}
const adapterData = arr2objAdapter(arr)
```
## 单例模式
```
// 创建弹框方法
const createLoginLayer = function() {
const div = document.createElement('div')
div.innerHTML = '登入浮框'
div.style.display = 'none'
document.body.appendChild(div)
return div
}
// 使单例模式和创建弹框代码解耦
// 创建单例模式
const getSingle = function(fn) {
const result
return function() {
return result || result = fn.apply(this, arguments)
}
}
const createSingleLoginLayer = getSingle(createLoginLayer)
document.getElementById('loginBtn').onclick = function() {
createSingleLoginLayer()
}
```
## 代理模式
> 代理模式的定义:为一个对象提供一个代用品或占位符,以便控制对它的访问。
### 虚拟代理
实现图片预加载
```
const myImage = (function() {
const imgNode = document.createElement('img')
document.body.appendChild(imgNode)
return {
setSrc: function(src) {
imgNode.src = src
}
}
})()
const proxyImage = (function() {
const img = new Image()
img.onload = function() { // http 图片加载完毕后才会执行
myImage.setSrc(this.src)
}
return {
setSrc: function(src) {
myImage.setSrc('loading.jpg') // 本地 loading 图片
img.src = src
}
}
})()
proxyImage.setSrc('http://loaded.jpg')
```
### 缓存代理
```
const demo =function (a,b) {
return a+b
}
const proxy =(function () {
const cached={}
return function (a,b) {
let cached_key =[].slice.call(arguments).toString()
if (cached[cached_key]) {
console.log("access cache");
return cached[cached_key]
}else{
console.log("no access cache");
cached[cached_key]=demo(a,b)
return cached[cached_key]
}
}
})()
console.log(proxy(1,2));
console.log(proxy(2,2));//第二次缓存
console.log(proxy(2,2));//第二次缓存
```
任意函数的缓存代理
```
const demo =function (a,b) {
return a+b
}
const proxy =function (func) {
const cached={}
return function (a,b) {
let cached_key =[].slice.call(arguments).toString()
if (cached[cached_key]) {
console.log("access cache");
return cached[cached_key]
}else{
console.log("no access cache");
cached[cached_key]=func(a,b)
return cached[cached_key]
}
}
}
const proxyCache=proxy(demo)
console.log(proxyCache(1,2));
console.log(proxyCache(2,2));//第二次缓存
console.log(proxyCache(2,2));//第二次缓存
console.log(proxyCache(2,2));//第二次缓存
```
## 订阅发布模式
```
class Event {
constructor() {
// 所有 eventType 监听器回调函数(数组)
this.listeners = {}
}
/**
* 订阅事件
* @param {String} eventType 事件类型
* @param {Function} listener 订阅后发布动作触发的回调函数,参数为发布的数据
*/
on(eventType, listener) {
if (!this.listeners[eventType]) {
this.listeners[eventType] = []
}
this.listeners[eventType].push(listener)
}
/**
* 发布事件
* @param {String} eventType 事件类型
* @param {Any} data 发布的内容
*/
emit(eventType, data) {
const callbacks = this.listeners[eventType]
if (callbacks) {
callbacks.forEach((c) => {
c(data)
})
}
}
}
const event = new Event()
event.on('open', (data) => {
console.log("ouput :",data)
})
event.emit('open', { open: true })
```
## 观察者模式
> **观察者模式**定义了一种一对多的依赖关系,让多个**观察者**对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有**观察者**对象,使它们能够自动更新
```
```
## 装饰者模式
> 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。
```
class A {
getContent() {
return '第一行内容'
}
render() {
console.log(this.getContent());
}
}
function decoratorOne(cla) {
const prevGetContent = cla.prototype.getContent
cla.prototype.getContent = function() {
console.log("这是输出前需要操作的内容");
return prevGetContent()
}
return cla
}
const B = decoratorOne(A)
new B().render()
/**
output
这是输出前需要操作的内容
第一行内容
*/
```
## 策略模式
```
function getYearEndBonus(strategyFn) {
if (!strategyFn) {
return {}
}
return strategyFn()
}
const bonusStrategy = {
A() {
return {
bonus: 50000,
prize: 'mac pro',
}
},
B() {
return {
bonus: 40000,
prize: 'mac air',
}
},
C() {
return {
bonus: 20000,
prize: 'iphone xr',
}
},
D() {
return {
bonus: 10000,
prize: 'ipad mini',
}
},
}
const performanceLevel = 'A'
getYearEndBonus(bonusStrategy[performanceLevel])
```
## 职责链模式
```
function order(options) {
return {
next: (callback) => callback(options),
}
}
function order500(options) {
const { orderType, pay } = options
if (orderType === 1 && pay === true) {
console.log('500 元定金预购, 得到 100 元优惠券')
return {
next: () => {},
}
} else {
return {
next: (callback) => callback(options),
}
}
}
function order200(options) {
const { orderType, pay } = options
if (orderType === 2 && pay === true) {
console.log('200 元定金预购, 得到 50 元优惠券')
return {
next: () => {},
}
} else {
return {
next: (callback) => callback(options),
}
}
}
function orderCommon(options) {
const { orderType, stock } = options
if (orderType === 3 && stock > 0) {
console.log('普通购买, 无优惠券')
return {}
} else {
console.log('库存不够, 无法购买')
}
}
order({
orderType: 1,
pay: true,
stock: 500,
}).next(order500)
.next(order200)
.next(orderCommon)
```
';