JavaScript設(shè)計(jì)模式-代理模式

定義

??代理模式是為一個(gè)對(duì)象提供一個(gè)占位符,以便控制對(duì)它的訪問。

描述

??代理模式是一種非常有意義的模式队贱,在生活中可以找到很多代理模式的場(chǎng)景欣除。比如住拭,明星都有經(jīng)紀(jì)人作為代理。如果想請(qǐng)明星來辦一場(chǎng)商業(yè)演出历帚,只能聯(lián)系他的經(jīng)紀(jì)人滔岳。經(jīng)紀(jì)人會(huì)把商業(yè)演出的細(xì)節(jié)和報(bào)酬都談好之后,再把合同交給明星簽挽牢。
??代理模式的關(guān)鍵是當(dāng)客戶不方便直接訪問一個(gè)對(duì)象或者不滿足需要的時(shí)候谱煤,提供一個(gè)替身對(duì)象來控制對(duì)這個(gè)對(duì)象的訪問,客戶實(shí)際上訪問的是替身對(duì)象禽拔。替身對(duì)象對(duì)請(qǐng)求做出一些處理之后刘离,再把請(qǐng)求轉(zhuǎn)交給本體對(duì)象。

應(yīng)用

??下面從小明送花追女孩的案例來熟悉代理模式的結(jié)構(gòu)奏赘,先看看不用代理模式的情況:

class Flower{
   constructor(name){
       this.name = name
   }
}
let xiaoming = {
    sendFlower: function( target ){
        let flower = new Flower('玫瑰花')
        target.receiveFlower( flower )
    }
}
let girl = {
    receiveFlower: function( flower ){
        console.log( '收到' + flower.name )
    }
};
xiaoming.sendFlower( girl )

引入女孩的閨蜜作為代理者:

class Flower {
    constructor(name) {
        this.name = name
    }
}

let xiaoming = {
    sendFlower: function (target) {
        let flower = new Flower('玫瑰花')
        target.receiveFlower(flower)
    }
}
let closeFriend = {
    receiveFlower(flower) {
        girl.listenGoodMood(() => {
            girl.receiveFlower(flower)
        })
    }
}

let girl = {
    receiveFlower: function (flower) {
        console.log('收到' + flower.name)
    },
    listenGoodMood: function (fn) {
        setTimeout(() => {fn()}, 10000)
}
}
xiaoming.sendFlower(closeFriend)

??現(xiàn)在改變故事的背景設(shè)定寥闪,假設(shè)當(dāng)girl在心情好的時(shí)候收到花,小明表白成功的幾率有60%磨淌,而當(dāng)girl在心情差的時(shí)候收到花疲憋,小明表白的成功率無限趨近于0。
??通過這個(gè)案例梁只,我們可以看到代理模式的價(jià)值缚柳。小明跟girl剛剛認(rèn)識(shí)兩天,還無法辨別girl什么時(shí)候心情好搪锣。如果不合時(shí)宜地把花送給girl秋忙,花被直接扔掉的可能性很大。但是girl的closeFriend卻很了解girl构舟,所以小明只管把花交給closedFriend灰追,closeFriend會(huì)監(jiān)聽girl的心情變化,然后選擇girl心情好的時(shí)候把花轉(zhuǎn)交給gril狗超。
??雖然這只是個(gè)虛擬的例子弹澎,但可以從中找到兩種代理模式的身影。girl的閨蜜可以幫組girl過濾掉一些請(qǐng)求努咐,比如送花的人年齡太大苦蒿、長(zhǎng)得太丑、太窮等渗稍,這種請(qǐng)求就可以直接在代理處被拒絕掉佩迟,這種代理叫做保護(hù)代理团滥。另外,現(xiàn)實(shí)中的花價(jià)值不菲报强,程序世界里灸姊,new Flower()也是一個(gè)代價(jià)昂貴的操作。把new Flower()的操作交給代理closeFriend去執(zhí)行躺涝,代理會(huì)選擇在girl心情好時(shí)再執(zhí)行new Flower()厨钻,這是代理模式的另一種形式,叫作虛擬代理坚嗜。虛擬代理把一些開銷很大的對(duì)象夯膀,延遲到真正需要它的時(shí)候才去創(chuàng)建。代碼如下:

let closedFriend = {
    receiveFlower() {
        girl.listenGoodMood(() => {
            let flower = new Flower('玫瑰花')
            girl.receiveFlower(flower)
        })
    }
}
圖片預(yù)加載

??在Web開發(fā)中苍蔬,圖片預(yù)加載是一種常用的技術(shù)诱建,如果直接給某個(gè)img標(biāo)簽節(jié)點(diǎn)設(shè)置src屬性,由于圖片過大或者網(wǎng)絡(luò)不佳碟绑,圖片的位置往往有段時(shí)間會(huì)是一片空白俺猿。常見的做法是先用一張loading圖片占位,然后用異步的方式加載圖片格仲,等圖片加載好了再把它填充到img節(jié)點(diǎn)里押袍,這種場(chǎng)景就很適合使用虛擬代理。
  下面來實(shí)現(xiàn)這個(gè)虛擬代理凯肋,首先創(chuàng)建一個(gè)普通的本體對(duì)象谊惭,這個(gè)對(duì)象負(fù)責(zé)往頁面中創(chuàng)建一個(gè)img標(biāo)簽,并且提供一個(gè)對(duì)外的setSrc接口侮东,外界調(diào)用這個(gè)接口圈盔,便可以給該img標(biāo)簽設(shè)置。

let myImage = (function(){
    let imgNode = document.createElement( 'img' )
    document.body.appendChild( imgNode )
    return {
        setSrc: function( src ){
            imgNode.src = src
        }
    }
})()
myImage.setSrc( 'coming.png' )

??設(shè)置網(wǎng)速很差的情況下悄雅,通過myImage驱敲,setSrc給該img元素設(shè)置src,可以看出宽闲,在圖片被加載好之前众眨,頁面有很長(zhǎng)的空白時(shí)間,用戶體驗(yàn)很不好容诬。
??現(xiàn)在引入代理對(duì)象proxyImage围辙,通過這個(gè)代理對(duì)象,在圖片被真正加載好之前放案,頁面中將出現(xiàn)一張占位的loading.gif,來提示用戶圖片正在加載矫俺。

let myImage = (function(){
    let imgNode = document.createElement( 'img' )
    document.body.appendChild( imgNode )
    return {
        setSrc: function( src ){
            imgNode.src = src
        }
    }
})()
let proxyImage = (function(){
    let img = new Image
    img.onload = function(){
        myImage.setSrc( this.src )
    }
    return {
        setSrc: function( src ){
            myImage.setSrc( 'loading.gif' )
            img.src = src
        }
    }
})()
proxyImage.setSrc( 'coming.png' )
代理模式的意義

??也許讀者有疑問吱殉,不過是實(shí)現(xiàn)一個(gè)小小的圖片預(yù)加載功能掸冤,及時(shí)不引入任何模式也能辦到,那么引入代理模式的好處究竟在哪里友雳?不使用代理稿湿,則圖片預(yù)加載的函數(shù)實(shí)現(xiàn)代碼如下:

let MyImage = (function(){
    let imgNode = document.createElement( 'img' )
    document.body.appendChild( imgNode )
    let img = new Image
    img.onload = function(){
        imgNode.src = img.src
    }
    return {
        setSrc: function( src ){
            imgNode.src = 'loading.gif'
            img.src = src
        }
    }
})()
MyImage.setSrc( 'coming.png' )

??這就要講到面向?qū)ο笤O(shè)計(jì)的原則——單一職責(zé)原則。
  單一職責(zé)原則指的是押赊,就一個(gè)類(通常也包括對(duì)象和函數(shù)等)而言饺藤,應(yīng)該僅有一個(gè)引起它變化的原因。如果一個(gè)對(duì)象承擔(dān)了多項(xiàng)職責(zé)流礁,就意味著這個(gè)對(duì)象將變得巨大涕俗,引起它變化的原因可能會(huì)有多個(gè)。面向?qū)ο笤O(shè)計(jì)鼓勵(lì)將行為分布到細(xì)粒度的對(duì)象之中神帅,如果一個(gè)對(duì)象承擔(dān)的職責(zé)過多再姑,等于把這些職責(zé)耦合到了一起,這種耦合會(huì)導(dǎo)致脆弱和低內(nèi)聚的設(shè)計(jì)找御。當(dāng)變化發(fā)生時(shí)元镀,設(shè)計(jì)可能會(huì)遭到意外的破壞。
  職責(zé)被定義為“引起變化的原因”霎桅。上面代碼中的MyImage對(duì)象除了負(fù)責(zé)給img節(jié)點(diǎn)設(shè)置src外栖疑,還要負(fù)責(zé)預(yù)加載圖片。在處理其中一個(gè)職責(zé)時(shí)滔驶,有可能因?yàn)槠鋸?qiáng)耦合性影響另外一個(gè)職責(zé)的實(shí)現(xiàn)遇革。
  另外,在面向?qū)ο蟮某绦蛟O(shè)計(jì)中瓜浸,大多數(shù)情況下澳淑,若違反其他任何原則,同時(shí)將違反開放——封閉原則插佛。如果只是從網(wǎng)絡(luò)上獲取一些體積很小的圖片杠巡,或者5年后的網(wǎng)速快到根本不再需要預(yù)加載,可能希望把預(yù)加載圖片的這段代碼從MyImage對(duì)象里刪掉雇寇。這時(shí)候就不得不改動(dòng) MyImage 對(duì)象了氢拥。實(shí)際上,需要的只是給img節(jié)點(diǎn)設(shè)置src锨侯,預(yù)加載圖片只是一個(gè)錦上添花的功能嫩海。如果能把這個(gè)操作放在另一個(gè)對(duì)象里面,自然是一個(gè)非常好的方法囚痴。于是代理的作用在這里就體現(xiàn)出來了叁怪,代理負(fù)責(zé)預(yù)加載圖片,預(yù)加載的操作完成之后深滚,把請(qǐng)求重新交給本體MyImage奕谭。
  縱觀整個(gè)程序涣觉,并沒有改變或者增加MyImage的接口,但是通過代理對(duì)象血柳,實(shí)際上給系統(tǒng)添加了新的行為官册。這是符合開放——封閉原則的。給img節(jié)點(diǎn)設(shè)置 src 和圖片預(yù)加載這兩個(gè)功能难捌, 被隔離在兩個(gè)對(duì)象里膝宁,它們可以各自變化而不影響對(duì)方。何況就算有一天不再需要預(yù)加載根吁, 那么只需要改成請(qǐng)求本體而不是請(qǐng)求代理對(duì)象即可员淫。

代理和本體接口的一致性

??代理對(duì)象和本體都對(duì)外提供了setSrc方法,在客戶看來婴栽,代理對(duì)象和本體是一致的满粗, 代理接手請(qǐng)求的過程對(duì)于用戶來說是透明的,用戶并不清楚代理和本體的區(qū)別愚争,這樣做有兩個(gè)好處:1映皆、用戶可以放心地請(qǐng)求代理,只關(guān)心是否能得到想要的結(jié)果轰枝;2捅彻、在任何使用本體的地方都可以替換成使用代理。

虛擬代理合并HTTP請(qǐng)求

??在Web開發(fā)中鞍陨,也許最大的開銷就是網(wǎng)絡(luò)請(qǐng)求步淹。假設(shè)在做一個(gè)文件同步的功能,選中一個(gè)checkbox時(shí)诚撵,它對(duì)應(yīng)的文件就會(huì)被同步到另外一臺(tái)備用服務(wù)器上面缭裆。
??首先,在頁面中放置好這些checkbox節(jié)點(diǎn):

<body>
    <input type="checkbox" id="1"></input>1
    <input type="checkbox" id="2"></input>2
    <input type="checkbox" id="3"></input>3
    <input type="checkbox" id="4"></input>4
    <input type="checkbox" id="5"></input>5
    <input type="checkbox" id="6"></input>6
    <input type="checkbox" id="7"></input>7
    <input type="checkbox" id="8"></input>8
    <input type="checkbox" id="9"></input>9
</body>

??接下來寿烟,給這些checkbox綁定點(diǎn)擊事件澈驼,并且在點(diǎn)擊的同時(shí)往另一臺(tái)服務(wù)器同步文件。

let synchronousFile = function( id ){
    console.log( '開始同步文件筛武,id 為: ' + id )
}
let checkboxs = document.getElementsByTagName( 'input' );
for ( let i = 0, c; c = checkboxs[ i++ ]; ){
    c.onclick = function(){
        if ( this.checked === true ){
            synchronousFile( this.id )
        }
    }
}

??當(dāng)選中3個(gè)checkbox的時(shí)候缝其,依次往服務(wù)器發(fā)送了3次同步文件的請(qǐng)求∨橇可以預(yù)見内边,如此頻繁的網(wǎng)絡(luò)請(qǐng)求將會(huì)帶來相當(dāng)大的開銷。
??解決方案是可以通過一個(gè)代理函數(shù)proxySynchronousFile來收集一段時(shí)間之內(nèi)的請(qǐng)求待锈,最后一次性發(fā)送給服務(wù)器漠其。比如等待2秒之后才把這2秒之內(nèi)需要同步的文件ID打包發(fā)給服務(wù)器,如果不是對(duì)實(shí)時(shí)性要求非常高的系統(tǒng),2秒的延遲不會(huì)帶來太大副作用辉懒,卻能大大減輕服務(wù)器的壓力阳惹。

let synchronousFile = function( id ){
    console.log( '開始同步文件,id 為: ' + id )
}

let proxySynchronousFile = (function(){
    let cache = [], // 保存一段時(shí)間內(nèi)需要同步的ID
        timer // 定時(shí)器
    return function( id ){
        cache.push( id )
        if ( timer ){ // 保證不會(huì)覆蓋已經(jīng)啟動(dòng)的定時(shí)器
            return
        }
        timer = setTimeout(function(){
            synchronousFile( cache.join( ',' ) ) // 2 秒后向本體發(fā)送需要同步的ID 集合
            clearTimeout( timer ) // 清空定時(shí)器
            timer = null
            cache.length = 0 // 清空ID 集合
        }, 2000 )
    }
})()

let checkboxs = document.getElementsByTagName( 'input' )
for ( let i = 0, c; c = checkboxs[ i++ ] ){
    c.onclick = function(){
        if ( this.checked === true ){
            proxySynchronousFile( this.id )
        }
    }
}
緩存代理

??緩存代理可以為一些開銷大的運(yùn)算結(jié)果提供暫時(shí)的存儲(chǔ)眶俩,在下次運(yùn)算時(shí),如果傳遞進(jìn)來的參數(shù)跟之前一致快鱼,則可以直接返回前面存儲(chǔ)的運(yùn)算結(jié)果颠印。
??下面是一個(gè)計(jì)算乘積的例子,先創(chuàng)建一個(gè)用于求乘積的函數(shù):

var mult = function(){
    console.log( '開始計(jì)算乘積' );
    var a = 1;
    for ( var i = 0, l = arguments.length; i < l; i++ ){
        a = a * arguments[i];
    }
    return a;
};
mult( 2, 3 ); // 輸出:6
mult( 2, 3, 4 ); // 輸出:24

??然后加入緩存代理函數(shù):

let proxyMult = (function(){
    let cache = {}
    return function(){
        let args = Array.prototype.join.call( arguments, ',' )
        if ( args in cache ){
            return cache[ args ]
        }
        return cache[ args ] = mult.apply( this, arguments )
    }
})()

proxyMult( 1, 2, 3, 4 ) // 輸出:24
proxyMult( 1, 2, 3, 4 ) // 輸出:24

??當(dāng)?shù)诙握{(diào)用proxyMult(1,2,3,4)的時(shí)候抹竹,本體mult函數(shù)并沒有被計(jì)算线罕,proxyMult直接返回了之前緩存好的計(jì)算結(jié)果。通過增加緩存代理的方式窃判,mult函數(shù)可以繼續(xù)專注于自身的職責(zé)——計(jì)算乘積钞楼,緩存的功能是由代理對(duì)象實(shí)現(xiàn)的。
  在項(xiàng)目中常常遇到分頁的需求袄琳,同一頁的數(shù)據(jù)理論上只需要去后臺(tái)拉取一次询件,這些已經(jīng)拉取到的數(shù)據(jù)在某個(gè)地方被緩存之后,下次再請(qǐng)求同一頁的時(shí)候唆樊,便可以直接使用之前的數(shù)據(jù)宛琅。顯然這里也可以引入緩存代理,實(shí)現(xiàn)方式跟計(jì)算乘積的例子差不多逗旁,唯一不同的是嘿辟,請(qǐng)求數(shù)據(jù)是個(gè)異步的操作,無法直接把計(jì)算結(jié)果放到代理對(duì)象的緩存中片效,而是要通過回調(diào)的方式红伦。

其他代理模式

??代理模式的變體種類非常多,還包括以下幾種:
  1. 防火墻代理:控制網(wǎng)絡(luò)資源的訪問淀衣,保護(hù)主題不讓“壞人”接近昙读。
??2.遠(yuǎn)程代理:為一個(gè)對(duì)象在不同的地址空間提供局部代表。
  3. 保護(hù)代理:用于對(duì)象應(yīng)該有不同訪問權(quán)限的情況舌缤。
  4. 智能引用代理:取代了簡(jiǎn)單的指針箕戳,它在訪問對(duì)象時(shí)執(zhí)行一些附加操作,比如計(jì)算一個(gè)對(duì)象被引用的次數(shù)国撵。
  5陵吸、寫時(shí)復(fù)制代理:通常用于復(fù)制一個(gè)龐大對(duì)象的情況。寫時(shí)復(fù)制代理延遲了復(fù)制的過程介牙,當(dāng)對(duì)象被真正修改時(shí)壮虫,才對(duì)它進(jìn)行復(fù)制操作。寫時(shí)復(fù)制代理是虛擬代理的一種變體,DLL(操作系統(tǒng)中的動(dòng)態(tài)鏈接庫)是其典型運(yùn)用場(chǎng)景囚似。

小結(jié)

??代理模式包括許多小分類剩拢,在javascript開發(fā)中最常用的是虛擬代理和緩存代理。雖然代理模式非常有用饶唤,但在編寫業(yè)務(wù)代碼時(shí)徐伐,往往不需要去預(yù)先猜測(cè)是否需要使用代理模式。當(dāng)真正發(fā)現(xiàn)不方便直接訪問某個(gè)對(duì)象的時(shí)候募狂,再編寫代理也不遲办素。

參考文獻(xiàn)

《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市祸穷,隨后出現(xiàn)的幾起案子性穿,更是在濱河造成了極大的恐慌,老刑警劉巖雷滚,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件需曾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祈远,警方通過查閱死者的電腦和手機(jī)呆万,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绊含,“玉大人桑嘶,你說我怎么就攤上這事」洌” “怎么了逃顶?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)充甚。 經(jīng)常有香客問我以政,道長(zhǎng),這世上最難降的妖魔是什么伴找? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任盈蛮,我火速辦了婚禮,結(jié)果婚禮上技矮,老公的妹妹穿的比我還像新娘抖誉。我一直安慰自己,他們只是感情好衰倦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布袒炉。 她就那樣靜靜地躺著,像睡著了一般樊零。 火紅的嫁衣襯著肌膚如雪我磁。 梳的紋絲不亂的頭發(fā)上孽文,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音夺艰,去河邊找鬼芋哭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛郁副,可吹牛的內(nèi)容都是我干的减牺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼霞势,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼烹植!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起愕贡,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巷屿,沒想到半個(gè)月后固以,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嘱巾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年憨琳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旬昭。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篙螟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出问拘,到底是詐尸還是另有隱情遍略,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布骤坐,位于F島的核電站绪杏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纽绍。R本人自食惡果不足惜蕾久,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拌夏。 院中可真熱鬧僧著,春花似錦、人聲如沸障簿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卷谈。三九已至杯拐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背端逼。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工朗兵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人顶滩。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓余掖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親礁鲁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盐欺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 代理模式 代理是一個(gè)對(duì)象,它可以用來控制對(duì)本體對(duì)象的訪問仅醇,它與本體對(duì)象實(shí)現(xiàn)了同樣的接口冗美,代理對(duì)象會(huì)把所有的調(diào)用方法...
    塵中老閱讀 364評(píng)論 0 0
  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情析二,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式粉洼。簡(jiǎn)單...
    舟漁行舟閱讀 7,761評(píng)論 2 17
  • javascript設(shè)計(jì)模式與開發(fā)實(shí)踐 設(shè)計(jì)模式 每個(gè)設(shè)計(jì)模式我們需要從三點(diǎn)問題入手: 定義 作用 用法與實(shí)現(xiàn) 單...
    穿牛仔褲的蚊子閱讀 4,062評(píng)論 0 13
  • 工廠模式 單體模式 模塊模式 代理模式 職責(zé)鏈模式 命令模式 模板方法模式 策略模式 發(fā)布-訂閱模式 中介者模式 ...
    HelloJames閱讀 1,008評(píng)論 0 6
  • 代理是一個(gè)對(duì)象,它可以用來控制對(duì)本體對(duì)象的訪問叶摄,它與本體對(duì)象實(shí)現(xiàn)了同樣的接口属韧,代理對(duì)象會(huì)把所有的調(diào)用方法傳遞給本體...
    JSUED閱讀 297評(píng)論 0 0