定义
代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
条件
代理模式中需要保持代理和本体接口的一致性,这样做我们有两个好处:
- 用户可以放心地请求代理,他只关心是否能得到想要的结果。
- 在任何使用本体的地方都可以替换成使用代理。
代理实例
虚拟代理实现图片预加载
<template>
<img ref="imgNode" src="" alt="" srcset="">
</template>
<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue'
import imgsrc from '../assets/logo.png'
export default defineComponent({
setup() {
const imgNode = ref(null);
onMounted(() => {
// 本体对象
const myImage = (src) => {
imgNode.value.src = src;
}
// 代理对象
const proxyImg = (() => {
const img = new Image;
img.onload = function(){
myImage(this.src)
}
return function(src){
myImage(imgsrc)
img.src= src;
}
})()
proxyImg('https://www.cnblogs.com/images/logo.svg?v=R9M0WmLAIPVydmdzE2keuvnjl-bPR7_35oHqtiBzGsM')
// 不需要预加载效果可直接替换
// myImage('https://www.cnblogs.com/images/logo.svg?v=R9M0WmLAIPVydmdzE2keuvnjl-bPR7_35oHqtiBzGsM')
})
return {
imgNode,
}
},
})
</script>
虚拟代理合并http请求
<template>
<input type="checkbox" id="1" @click="clickHandle('1', $event)">1
<input type="checkbox" id="2" @click="clickHandle('2', $event)">2
<input type="checkbox" id="3" @click="clickHandle('3', $event)">3
<input type="checkbox" id="4" @click="clickHandle('4', $event)">4
<input type="checkbox" id="5" @click="clickHandle('5', $event)">5
<input type="checkbox" id="6" @click="clickHandle('6', $event)">6
<input type="checkbox" id="7" @click="clickHandle('7', $event)">7
<input type="checkbox" id="8" @click="clickHandle('8', $event)">8
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
methods: {
synFile(id) {
console.log('同步'+id)
},
proxySynFile: (function() {
const cache = [];
let timer = null;
return function(id){
cache.push(id);
if (timer) return;
timer = setTimeout(() => {
this.synFile(cache.join(','))
clearTimeout(timer)
timer = null
cache.length = 0
}, 2000)
}
})(),
clickHandle(id, e) {
if (e.target.checked) this.proxySynFile(id)
}
}
})
</script>
缓存代理
const mult = function() {
console.log(arguments)
let a = 1;
for (let i = 0; i < arguments.length; i++) {
a = a * arguments[i];
}
return a;
}
const plus = function() {
let a = 0;
for (let i = 0; i < arguments.length; i++) {
a = a + arguments[i];
}
return a;
}
const proxyFunc = function(fn) {
const cache = {};
return function() {
const args = Array.prototype.join.call(arguments, ',')
if (args in cache) {
return cache[args]
}
console.log(arguments)
return cache[args] = fn.apply(this, arguments)
}
}
const proxyMult = proxyFunc(mult)
const proxyPlus = proxyFunc(plus)
console.log(proxyMult(1, 2, 3, 4))
console.log(proxyPlus(1, 2, 3, 4))
其他代理模式
- 防火墙代理:控制网络资源的访问,保护主题不让“坏人”接近。
- 远程代理:为一个对象在不同的地址空间提供局部代表,在Java中,远程代理可以是另一个虚拟机中的对象。
- 保护代理:用于对象应该有不同访问权限的情况。
- 智能引用代理:取代了简单的指针,它在访问对象时执行一些附加操作,比如计算一个对象被引用的次数。
- 写时复制代理:通常用于复制一个庞大对象的情况。写时复制代理延迟了复制的过程,当对象被真正修改时,才对它进行复制操作。写时复制代理是虚拟代理的一种变体,DLL(操作系统中的动态链接库)是其典型运用场景。