成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端必須懂的設計模式-代理模式

開發 前端
代碼可以隨時從程序中去掉,而不用對其他部分的代碼進行修改,在實際場景中,隨著版本的迭代可能會有多種原因不再需要代理,那么就可以容易的將代理對象換成原對象的調用

代理模式

代理模式 (Proxy Pattern)又稱委托模式,它為目標對象創造了一個代理對象,以控制對目標對象的訪問,也可以理解為對外暴露的接口并不是原對象。通俗地講,生活中也有比較常見的代理模式:中介、寄賣、經紀人等等。而這種模式存在的意義在于當訪問者與被訪問者不方便直接訪問/接觸的情況下,提供一個替身來處理事務流程,實際訪問的是替身,替身將事務做了一些處理/過濾之后,再轉交給本體對象以減輕本體對象的負擔。

常見代理模式

  • 保護代理
  • 虛擬代理
  • 緩存代理
  • 。。。

實現

保護代理:

/**
* 保護代理簡單實現
* client向服務端發送一個請求
* proxy代理請求轉發給服務端
* 服務端處理請求
*/

// 改進前
const Request = function () {};
const client = {
requestTo: (server) => {
const req = new Request();
server.receiveRequest(req);
},
};
const server = {
handleRequest: (request) => {
console.log('receive request: ', request);
},
};
const proxy = {
receiveRequest: (request) => {
console.log('proxy request: ', request);
server.handleRequest(request);
},
};
client.requestTo(proxy);

// 改進后
const proxy = {
receiveRequest: (request) => {
// 校驗身份
const pass = validatePassport(request);
if (pass) {
// 監聽服務端 ready 后代理請求
server.listenReady(() {
console.log('proxy request: ', request);
server.handleRequest(request);
});
}
},
};

虛擬代理:虛擬代理是把一些開銷很大的對象或者方法,延遲到真正需要它的時候才去創建執行

// 圖片懶加載
const img = (() => {
const imgNode = document.createElement('img');
imgNode.style.width = '200px'
document.body.appendChild(imgNode);
return {
setSrc: (src) => {
imgNode.src = src;
},
setLoading: () => {
imgNode.src = './img/loading.gif'
}
};
})();
const proxyImg = ((source) => {
// 替身圖片對象
const tempImg = new Image();
// 監聽資源加載完成,將資源替換給實體圖片對象
tempImg.onload = function () {
source.setSrc(this.src);
};
return {
// 代理開始將實體對象設置為loading狀態,使用替身對象開始加載圖片資源
setSrc:(src)=>{
source.setLoading()
tempImg.src = src;
}
}
})(img);
proxyImg.setSrc('https://static-prod.retech.us/onder-cender/DoorDash.svg')

// ------------------------------------------------------------

// 合并http請求
//上傳請求
let upload = function(ids){
$.ajax({
data: {
id:ids
}
})
}

//代理合并請求
let proxy = (function(){
let cache = [],
timer = null;
return function(id){
cache[cache.length] = id;
if(timer) return false;
timer = setTimeout(function(){
upload(cache.join(','));
clearTimeout(timer);
timer = null;
cache = [];
},2000);
}
})();

// 綁定點擊事件
let checkbox = document.getElementsByTagName( "input" );
for(var i= 0, c; c = checkbox[i++];){
c.onclick = function(){
if(this.checked === true){
proxy(this.id);
}
}
}

緩存代理:緩存代理可以作為一些開銷大的運算結果提供暫時的存儲,下次運算時,如果傳遞進來的參數跟之前一致,則可以直接返回前面存儲的運算結果

/**
* 對于一些比較消耗性能的操作
* 可以將結果緩存起來
* 在獲取結果時優先從緩存中取,緩存中沒有再計算
*/

let fibonacci = function(n){
if(n === 1 || n === 0 ) return n;
return fibonacci(n-1) + fibonacci(n-2);
}

//緩存代理
let proxy = (function(fn){
let cache = {};
return function(){
let args = Array.prototype.join.call(arguments,',');
if(args in cache){
return cache[args];
}
return cache[args] = fn.apply(this,arguments);
}
})(fibonacci);

proxy(3)

實際案例

Vue中的代理模式:

// 將數據、方法、計算屬性等代理到組件實例上
let vm = new Vue({
data: {
msg: 'hello',
vue: 'vue'
},
computed:{
helloVue(){
return this.msg + ' ' + this.vue
}
},
mounted(){
console.log(this.helloVue)
}
})

源碼分析:

export function proxy (target: Object, sourceKey: string, key: string) {
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
}
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val
}
Object.defineProperty(target, key, sharedPropertyDefinition)
}

export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}

function initData (vm: Component) {
let data = vm.$options.data
// 初始化 _data,組件中 data 是函數,調用函數返回結果
// 否則直接返回 data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
if (!isPlainObject(data)) {
data = {}
process.env.NODE_ENV !== 'production' && warn(
'data functions should return an object:\n' +
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
vm
)
}
// proxy data on instance
// 獲取 data 中的所有屬性
const keys = Object.keys(data)
// 獲取 props / methods
const props = vm.$options.props
const methods = vm.$options.methods
let i = keys.length
// 判斷 data 上的成員是否和 props/methods 重名
while (i--) {
const key = keys[i]
if (process.env.NODE_ENV !== 'production') {
if (methods && hasOwn(methods, key)) {
warn(
`Method "${key}" has already been defined as a data property.`,
vm
)
}
}
if (props && hasOwn(props, key)) {
process.env.NODE_ENV !== 'production' && warn(
`The data property "${key}" is already declared as a prop. ` +
`Use prop default value instead.`,
vm
)
} else if (!isReserved(key)) {
proxy(vm, `_data`, key)
}
}
// observe data
// 響應式處理
observe(data, true /* asRootData */)
}

總結

在面向對象的編程中,代理模式的合理使用能夠很好地體現下面兩條設計原則:

  1. 單一職責原則: 面向對象設計中鼓勵將不同的職責分布到細粒度的對象中,Proxy 在原對象的基礎上進行了功能的衍生而又不影響原對象,符合松耦合高內聚的設計理念。
  2. 開放-封閉原則:代碼可以隨時從程序中去掉,而不用對其他部分的代碼進行修改,在實際場景中,隨著版本的迭代可能會有多種原因不再需要代理,那么就可以容易的將代理對象換成原對象的調用

對于代理模式 Proxy 作用主要體現在三個方面:

  1. 攔截和監視外部對對象的訪問
  2. 降低對象的復雜度
  3. 在復雜操作前對操作進行校驗或對所需資源進行管理

?文章出自:??前端餐廳ReTech??,如有轉載本文請聯系前端餐廳ReTech今日頭條號。

github:https://github.com/zuopf769

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2022-11-14 08:44:56

前端門面模式接口

2012-02-29 09:41:14

JavaScript

2012-01-13 15:59:07

2021-06-29 08:54:23

設計模式代理模式遠程代理

2010-03-25 08:52:30

PHP設計模式代理模式

2022-09-07 08:25:08

代理模式設計模式代碼

2022-02-06 22:30:36

前端設計模式

2022-01-19 08:21:12

設計裝飾器模式

2022-02-11 10:22:48

模版模式語言

2022-02-15 22:45:00

前端設計模式

2024-02-26 11:52:38

代理模式設計

2022-01-29 22:12:35

前端模式觀察者

2022-02-13 23:33:24

設計模式Java

2019-07-29 10:39:39

前端性能優化緩存

2023-12-26 08:20:40

2017-04-17 21:33:01

前端開發javascript嚴格模式

2021-09-08 07:18:30

代理模式對象

2021-04-19 21:25:48

設計模式到元

2022-05-27 11:33:02

前端代碼設計模式

2024-04-16 00:07:36

設計模式代理模式替身
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 五月综合色啪 | 久久久久久久av麻豆果冻 | 91影库 | 在线成人av | 亚洲精品视频在线观看免费 | 亚洲精品二区 | 中文一区二区 | 在线精品一区二区 | 国产精品高潮呻吟久久av黑人 | 日韩在线不卡视频 | 在线观看国产www | av在线黄| 亚洲一区在线日韩在线深爱 | 婷婷去俺也去 | 精品一区二区三区在线播放 | 国产高清在线精品一区二区三区 | 国产成人免费 | 国精产品一区一区三区免费完 | 日本精品一区二区 | 成人免费淫片aa视频免费 | 久久成人国产精品 | 91精品国产高清久久久久久久久 | 亚洲精品视频一区 | 女同久久另类99精品国产 | 午夜男人视频 | 国产黄色麻豆视频 | 日本高清不卡视频 | 日本在线小视频 | 色视频欧美 | 日韩福利电影 | 亚洲一级av毛片 | 中文字幕丁香5月 | 精品久久精品 | 日本国产一区二区 | 日本视频在线播放 | 久久精品欧美一区二区三区不卡 | 一区二区三区在线 | 日本在线视频一区二区 | 国产精品免费播放 | 天天操天天插 | 一区二区三区视频在线观看 |