摘要:代理模式代理模式為一個(gè)對(duì)象提供一個(gè)代用品或占位符,以便控制對(duì)于它訪問。這種代理就叫虛擬代理。保護(hù)代理用于對(duì)象應(yīng)該有不同訪問權(quán)限情況。寫時(shí)復(fù)制代理時(shí)虛擬代理的一種變體。
一、創(chuàng)建型設(shè)計(jì)模式(三大類設(shè)計(jì)模式)
創(chuàng)建型設(shè)計(jì)模式 --"創(chuàng)建"說明該類別里面的設(shè)計(jì)模式就是用來創(chuàng)建對(duì)象的,也就是在不同的場(chǎng)景下我們應(yīng)該選用什么樣的方式來創(chuàng)建對(duì)象。
1. 單例模式==單例模式(Singleton)==:確保一個(gè)類只有一個(gè)實(shí)例,提供一個(gè)全局訪問點(diǎn)。
==標(biāo)準(zhǔn)==單例實(shí)現(xiàn)
通常要實(shí)現(xiàn)一個(gè)單例模式并不復(fù)雜,無非就是用一個(gè)變量來標(biāo)記當(dāng)前是否已經(jīng)為了某個(gè)類創(chuàng)建過對(duì)象了,如果創(chuàng)建過對(duì)象了,則在下一次獲取該類的實(shí)例時(shí),直接返回之前創(chuàng)建的對(duì)象。
/*單例實(shí)現(xiàn)代碼如下:*/ var Singleton = function(name) { this.name = name; this.instance = null; }; Singleton.prototype.getName = function() { alert(this.name); }; Singleton.getInstance = function(name) { if (!this.instance) { this.instance = new Singleton(name); } return this.instance; }; //測(cè)試 var xiaoyi = Singleton.getInstance("小一"); var xiaoer = Singleton.getInstance("小二"); alert( xiaoyi === xiaoer ); //true
/*另一種寫法*/ var Singleton = function(name) { this.name = name; }; Singleton.prototype.getName = function() { alert ( this.name ); }; Singleton.getInstance = (function(){ var instance = null; return function(name) { if ( !instance ) instance = new Singleton(name); } return instance; })(); //測(cè)試 var xiaoyi = Singleton.getInstance("小一"); var xiaoer = Singleton.getInstance("小二"); alert( xiaoyi === xiaoer ); //true
結(jié)論: 無論我們創(chuàng)建的實(shí)例叫什么他總是同一個(gè)實(shí)例,這種寫法實(shí)現(xiàn)的單例雖然較為簡(jiǎn)單,但是增加了類的“不透明性”,使用這必須知道這個(gè)是一個(gè)單例類。
透明單例
(試想一下,當(dāng)我們單擊登錄按鈕的時(shí)候,頁面中會(huì)出現(xiàn)一個(gè)登錄浮窗,這個(gè)浮窗應(yīng)該是唯一的,無論單機(jī)多少次按鈕,每個(gè)浮窗只會(huì)被創(chuàng)建一次,那么這個(gè)浮窗就能用單例模式來創(chuàng)建)
現(xiàn)在我們來實(shí)現(xiàn)一個(gè)“透明”的單例類,這樣用戶使用這個(gè)類就能像使用其他類一樣。我們將創(chuàng)建CreateDiv單例類,他的作用是負(fù)責(zé)在頁面創(chuàng)建唯一的div節(jié)點(diǎn)。
/*使用透明的單例類來創(chuàng)建div*/ var CreateDiv = (function() { var instance; var CreateDiv = function( html ) {//傳入內(nèi)容 if(instance){ return instance; } this.html = html; //當(dāng)前 this.init(); return instance = this; }; CreateDiv.prototype.init = function() { var div = document.createElement("div"); div.innnerHTML = this.html; document.body.appendChild(div); }; return CreateDiv; })(); //測(cè)試 var xiaoyi = new CreateDiv("小一"); var xiaoer = new CreateDiv("小二"); alert( xiaoyi === xiaoer ); //true
結(jié)論上邊這個(gè)單例雖然“透明”了,但是為了把instance封裝起來,我們使用了自執(zhí)行匿名函數(shù)和閉包,并且讓匿名函數(shù)返回真正的Singleton構(gòu)造方法。增加了程序復(fù)雜度。
CreateDiv的構(gòu)造函數(shù)實(shí)際上負(fù)責(zé)了兩件事情。第一:創(chuàng)建對(duì)象,執(zhí)行初始話方法,第二:保證只有一個(gè)實(shí)例對(duì)象。違背了單一原則。(單一原則:一個(gè)類最好只負(fù)責(zé)一項(xiàng)功能??刂祁惖牧6龋?br>
==導(dǎo)致的結(jié)果==當(dāng)我們要使用這個(gè)類實(shí)例多個(gè)對(duì)象的時(shí)候,就必須要把控制創(chuàng)建唯一對(duì)象的那段去掉,這種修改會(huì)給我們帶來不必要的煩惱。
javascript中的單例
關(guān)于前邊所提到的幾種單例模式的實(shí)現(xiàn),更多是接近于傳統(tǒng)面向?qū)ο笳Z言中的實(shí)現(xiàn),單例從類創(chuàng)建而來,在以類為中心的語言中,這是一種很自然的做法。比如java中如果需要某個(gè)對(duì)象,就必須先定義一個(gè)類,對(duì)象總是從類中創(chuàng)建而來。
就javascript而言,它其實(shí)是一門無類(class-free)語言,在javascript中,既然我們只需要一個(gè)“唯一”的對(duì)象,為什么要先創(chuàng)建一個(gè)類?在javascript中經(jīng)常把全局變量當(dāng)成單例來使用。
var a = {};
用這種形式創(chuàng)建對(duì)象a,a是獨(dú)一無二的。聲明于全局下,提供全局訪問點(diǎn)也是必然的。
這種做法缺陷:全局變量存在很多問題,容易造成命名空間污染。自己命名變量隨時(shí)可能被別人覆蓋掉了?!咎幚怼孔鳛殚_發(fā)這我們應(yīng)該盡量減少全局變量的使用,即使使用也要把它的污染降到最低。
幾種降低全局變量帶來的命名污染。
使用命名空間
var namespace = { a: {}, b: {}, };
使用閉包封裝私有變量
var user = (function(){ var _name = "sven", _age = 29; return { getUserInfo: function() { return _name + "-" _age; } } })()
通用的惰性單例
var getSingle = function(fn) { var result; return function() { return result || (result = fn.apply(this, arguments)); }; }; var createLoginLayer = function() { var div = document.createElement("div"); div.innerHTML = "我是登錄浮窗"; div.style.display = "none"; document.body.appendChild(div); return div; }; var CreateSingleLoginLayer = getSingle(createLoginLayer); document.getElementById("loginBtn").onclick = function() { var loginLayer = CreateSingleLoginLayer(); loginLayer.style.display = "block"; }; var CreteSingleIframe = getSingle(function() { //動(dòng)態(tài)加載第三頁面 var iframe = document.createElement("iframe"); document.body.appendChild(iframe); return iframe; }); document.getElementById("loginBtn").onclick = function() { var loginLaryer = createSingleIframe(); loginLayer.src = "http://baidu.com" }
結(jié)論 以上我們把創(chuàng)建實(shí)例對(duì)象的職責(zé)和管理單例的職責(zé)分別放置在兩個(gè)方法里,這兩個(gè)方法可以獨(dú)立變化而互不影響,而當(dāng)他們連接在一起,就完成了創(chuàng)建唯一實(shí)例對(duì)象的功能。
總結(jié)當(dāng)需求實(shí)例唯一、命名空間時(shí),就可以使用單例模式。結(jié)合閉包特性,用途廣泛。
二、結(jié)構(gòu)型設(shè)計(jì)模式結(jié)構(gòu)型設(shè)計(jì)模式 --關(guān)注于如何將類或者對(duì)象組合成更大的結(jié)構(gòu),以便在使用的時(shí)候更簡(jiǎn)化。
1. 代理模式==代理模式(proxy)==:為一個(gè)對(duì)象提供一個(gè)代用品或占位符,以便控制對(duì)于它訪問。
代理模式在生活中的場(chǎng)景
比如:每個(gè)明星都有經(jīng)紀(jì)人作為代理。如果想請(qǐng)明星來辦一場(chǎng)商業(yè)演出,那么只能聯(lián)系它的經(jīng)紀(jì)人。經(jīng)紀(jì)人會(huì)把商業(yè)演出的細(xì)節(jié)和報(bào)酬都談好之后,再把合同交給明星簽名確認(rèn)。
graph LR 客戶((圓))-->本體((圓)) graph LR 客戶((圓))-->代理((圓))-->本體((圓))
代理相當(dāng)于本體的替身,替身對(duì)請(qǐng)求做出一些處理后再把請(qǐng)求給本體對(duì)象。
故事場(chǎng)景
康康喜歡上瑪麗亞,康康在二月十四想送一束花表白瑪麗亞,剛好她兩有共同的朋友michael,所以康康就叫micheal幫忙送花給瑪麗亞。
/*用代碼來寫送花場(chǎng)景,首先是不通過(代理)*/ var Flower = function() {}; var kangkang = { //類 sendFlower: function(target) { //傳入送花目標(biāo) var flower = new Flower(); //實(shí)例一朵花 target.receiveFlower(flower); //花傳給maria } }; var maria = { //類 receiveFlower: function(flower) { //接受類 console.log("收到花了" + flower) } }; kangkang.sendFlower(maria);
/*代理送花代碼*/ var Flower = function() {}; var kangkang = { sendFlower: function(target){ var flower = new Flower(); target.receiveFlower(flower); } }; var michael = {//michael為代理 receiverFlower: function(flower) { maria.receiveFlower(flower); } }; var maria = { receiveFlower: function(flower) { console.log("收到花了" + flower) } }; kangkang.sendFlower(michael);
顯然看起來這樣送花不是有病? 能直接送到手為什么非要轉(zhuǎn)別人的手送花呢。其實(shí)不然,當(dāng)康康自己去送話,如果瑪麗亞心情號(hào)成功幾率有60%,但是心情差成功接近0,而通過jane的話jane可能較為了解瑪麗亞,選擇心情好的時(shí)候去送,這時(shí)候就事半功倍了。
/*心情好的時(shí)候送花*/ var Flower = function() {}; var kangkang = { sendFlower: function(target){ var flower = new Flower(); target.receiveFlower(flower); } }; var jane = {//jane為代理 receiverFlower: function(flower) { maria.listenGoodMood(function(){ //心情轉(zhuǎn)好是后送花 maria.receiveFlower(flower); }) } }; var maria = { receiveFlower: function(flower) { console.log("收到花了" + flower) }, listenGoodMood: function(fn) {//一秒后心情轉(zhuǎn)好 setTimeout(function() { if(true){fn()} fn(); }, 1000); } }; kangkang.sendFlower(jane);
保護(hù)代理和虛擬代理
從上面的例子我們可以看出這兩種代理的影子。代理jane可以幫助瑪麗亞過濾掉一些請(qǐng)求,比如說送花的人不是康康,這樣就直接可以在代理jane中被拒絕掉了。這種代理叫做保護(hù)代理。
假設(shè)new Flower一束花有期限,過期會(huì)凋謝,那么我們可以把new flower 交給代理jane去執(zhí)行,代理jane會(huì)選擇在瑪麗亞心情好的時(shí)候再去買花而后送花。這種代理就叫虛擬代理。(虛擬代理是把一些開銷很大的對(duì)象,延遲到真正需要它的時(shí)候再去創(chuàng)建。)
/*虛擬代理*/ var jane = {//jane為代理 receiverFlower: function(flower) { maria.listenGoodMood(function(){ //心情轉(zhuǎn)好是后送花 var flower = new Flower(); //延遲創(chuàng)建 flower 對(duì)象 maria.receiveFlower(flower); }) } };
虛擬代理實(shí)現(xiàn)圖片的預(yù)加載
如果直接給某個(gè)img設(shè)置src屬性的話,可能會(huì)由于網(wǎng)絡(luò)太差,圖片的位置往往有段時(shí)間會(huì)是一片空白,常見的作法就是用一張loading圖片占位,然后用異步的方式加載圖片,等圖片加載好了再把它填充把img節(jié)點(diǎn)中。這種場(chǎng)景就用虛擬代理。
/*創(chuàng)建一個(gè)圖片元素并且提供一個(gè)設(shè)置s"r"c的接口*/ var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return { setSrc: function(src) { imgNode.src = src; } } })(); /*引入代理ProxyImg對(duì)象,在圖片真正被加載好之前用一張展位的菊花圖來提示用戶正在加載。*/ var proxyImage = (function(){ var img = new Image; img.onload = function() { //當(dāng)真正的圖加載完了在把圖片塞給他 myImage.setSrc(this.src) } return { setSrc: function(src) { //一開始先設(shè)置一張菊花圖給他 myImage.setSrc("./loading.gif"); img.src = src; } } })(); proxyImage.setSrc("http://wangshangtupian.jpg"); //模擬的圖片
代理的意義
單一職責(zé)原則就一個(gè)類而言,應(yīng)僅有一個(gè)引起它變化的原因。
開放-封閉閉原則不用改變MyImage類或者添加接口,通過代理給系統(tǒng)添加了新的行為,這符合開閉原則。
結(jié)論當(dāng)我們不需要預(yù)加載的功能,我們只需要直接請(qǐng)求本體,而不需要請(qǐng)求代理,這就使用代理的靈活之處。
虛擬代理合并HTTP請(qǐng)求
先想象一下這樣一個(gè)場(chǎng)景:假設(shè)一個(gè)公司需要員工寫周報(bào),周報(bào)要交給總監(jiān)批閱,總監(jiān)手下有150個(gè)員工,如果我們每個(gè)人把周報(bào)發(fā)給總監(jiān),那總監(jiān)可能就不用工作了,每周看周報(bào)。如果將周報(bào)發(fā)給組長(zhǎng),組長(zhǎng)整理后再發(fā)給總監(jiān),那總監(jiān)就輕松多了。
/*需要做一個(gè)文件同步的功能,當(dāng)點(diǎn)擊checkbox同時(shí)往另一臺(tái)服務(wù)器同步文件,如果一秒點(diǎn)四個(gè)checkbox,那么網(wǎng)絡(luò)開銷會(huì)相當(dāng)大。我們可以通過一個(gè)代理函數(shù)來收集一段時(shí)間內(nèi)的請(qǐng)求,最后一次性發(fā)給服務(wù)器請(qǐng)求*/ 1 2 3 4 5 //給checkout 綁定事件 var synchronousFile = function(id) { console.log("開始同步文件, id為:" + id); }; var ProxySynchronousFile = (function(){ var cache = [],//保存一段事件內(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秒后向服務(wù)器發(fā)送id的集合 clearTimeout(timer); timer = null; cache.length = 0; //清空ID集合 }, 2000); } })(); var checkbox = document.getElementsByTagName("input"); for (var i = 0, c; c= checkbox[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é)果。
/*計(jì)算乘積*/ 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; } var proxyMult = (function(){ var cache = {}; return function() { var 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
總結(jié)代理模式應(yīng)用廣泛,比如說防火墻代理:控制網(wǎng)絡(luò)資源的訪問,保護(hù)主機(jī)不讓壞人破壞。遠(yuǎn)程代理:為一個(gè)對(duì)象在不同的地址空間提供局部代表。保護(hù)代理:用于對(duì)象應(yīng)該有不同訪問權(quán)限情況。智能引用代理:取代了簡(jiǎn)單的指針,他在訪問對(duì)象是執(zhí)行一些附加操作,比如計(jì)算一個(gè)對(duì)象被應(yīng)用的次數(shù)。寫時(shí)復(fù)制代理:通常用于復(fù)制一個(gè)龐大的對(duì)象的情況。寫時(shí)復(fù)制代理延遲了復(fù)制的過程。當(dāng)對(duì)象真正被修改時(shí),才對(duì)它進(jìn)行復(fù)制操作。寫時(shí)復(fù)制代理時(shí)虛擬代理的一種變體。更多就不再一一贅述了。
三、行為型設(shè)計(jì)模式行為型設(shè)計(jì)模式 --不單單涉及到類和對(duì)象,更關(guān)注于類或者對(duì)象之間的通訊交流。
1. 狀態(tài)模式==狀態(tài)模式(State Pattern)==:關(guān)鍵是區(qū)分事物內(nèi)部的狀態(tài),事物內(nèi)部的狀態(tài)改變往往會(huì)帶來事物行為的改變。
初識(shí)狀態(tài)模式
想象一下:有一個(gè)電燈,只有一個(gè)控制電燈的開關(guān)。當(dāng)電燈開著的時(shí)候按下開關(guān),電燈會(huì)切換到關(guān)閉狀態(tài);再按一次開關(guān),電燈將又被打開,同一個(gè)開關(guān)在不同的狀態(tài)下表現(xiàn)出來的行為是不一樣的。
var Light = function() { this.state = "off"; //電燈初始狀態(tài) this.button = null; //電燈開關(guān) } Light.prototype.init = function() { var button = document.createElement("button"). self = this; button.innerHTML = "開關(guān)"; this.button = document.body.appendChild(button); this.button.onclick = function() { self.buttonWasPressed();//開關(guān)按下的行為函數(shù) } }; Ligth.prototype.buttonWasPressed = function() { if (this.state === "off") { console.log("開燈"); this.state = "on"; } else if (this.state === "on") { console.log("關(guān)燈"); this.state = "off"; } }; var light = new Light(); light.init();
令人遺憾的是這個(gè)世界上的電燈并不是只有這一種。某個(gè)酒店的燈,按一下開關(guān)弱光,在按一下開關(guān)強(qiáng)光,再按一下開光關(guān)閉。
Ligth.prototype.buttonWasPressed = function() { if (this.state === "off") { console.log("弱光"); this.state = "ruoguang"; } else if (this.state === "ruoguang") { console.log("強(qiáng)光"); this.state = "qiangguang"; } else if (this.state === "qiangguang"){ console.log("關(guān)燈"); this.state = "off"; } };
這個(gè)buttonWasPressed很明顯違反了開放-閉合原則,每次新增或修改電燈的狀態(tài)都需要從新改動(dòng)buttonWasPressed方法中的代碼,這讓它成為一個(gè)非常不穩(wěn)定的方法。
/*讓我們改進(jìn)一下*/ var OffLightState = function(light){ this.light = light; } OffLightState.prototype.buttonWasPressed = function() { console.log("弱光"); this.light.setState(this.light.weakLightState); } var WeakLightState = function(light){ this.light = light; } WeakLightState.prototype.buttonWasPressed = function() { console.log("強(qiáng)光"); this.light.setState(this.light.strongLightState); } var strongLightState = function(light){ this.light = light; } strongLightState.prototype.buttonWasPressed = function() { console.log("關(guān)燈"); this.light.setState(this.light.OffLightState); } //改寫類 var Light = function() { this.OffLightState = new OffLightState(this); this.WeakLightState = new WeakLightState(this); this.strongLightState = new strongLightState(this); this.button = null; }; Light.prototype.init = function(){ var button = document.createElement("button"), self = this; this.button = document.body.appendChild(button); this.button.innerHTML = "開關(guān)"; this.currState = this.offLightState; //設(shè)置當(dāng)前狀態(tài) this.button.onclick = function(){ self.currState.buttonWasPressed(); } } Light.prototype.setState = function(newState){ this.currState = newState; }; var light = new Light(); light.init();
總結(jié)狀態(tài)模式的優(yōu)缺點(diǎn)
狀態(tài)模式定義了狀態(tài)與行為之間的關(guān)系,并將他們封裝在一個(gè)類里,通過增加新的狀態(tài),很容易增加新的狀態(tài)和轉(zhuǎn)換。
避免Context無限膨脹,狀態(tài)切換的邏輯被分布在狀態(tài)類中,也去掉了context原本過多的條件分支。
用對(duì)象代替字符串來記錄當(dāng)前的狀態(tài),使得狀態(tài)的切換更加一目了然。
context中的請(qǐng)求動(dòng)作和狀態(tài)類中封裝的行為可以非常容易的獨(dú)立變化而不互相影響。
缺點(diǎn):會(huì)在系統(tǒng)中定義許多的狀態(tài)類,編寫二十個(gè)狀態(tài)類是一項(xiàng)枯燥乏味的工作,而且系統(tǒng)中會(huì)因此增加不少對(duì)象,另外由于邏輯分布在狀態(tài)類中,雖然避開了不受歡迎的條件語句,但是也造成了邏輯分散的問題。我們無法在一個(gè)地方就看出整個(gè)狀態(tài)機(jī)的邏輯。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100058.html
摘要:訂閱模式的一個(gè)典型的應(yīng)用就是后面會(huì)寫一篇相關(guān)的讀書筆記。享元模式享元模式的核心思想是對(duì)象復(fù)用,減少對(duì)象數(shù)量,減少內(nèi)存開銷。適配器模式對(duì)目標(biāo)函數(shù)進(jìn)行數(shù)據(jù)參數(shù)轉(zhuǎn)化,使其符合目標(biāo)函數(shù)所需要的格式。 設(shè)計(jì)模式 單例模式 JS的單例模式有別于傳統(tǒng)面向?qū)ο笳Z言的單例模式,js作為一門無類的語言。使用全局變量的模式來實(shí)現(xiàn)單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個(gè)實(shí)例...
摘要:代理模式,迭代器模式,單例模式,裝飾者模式最少知識(shí)原則一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少地與其他實(shí)體發(fā)生相互作用。迭代器模式可以將迭代的過程從業(yè)務(wù)邏輯中分離出來,在使用迭代器模式之后,即不用關(guān)心對(duì)象內(nèi)部構(gòu)造也可以按順序訪問其中的每個(gè)元素。 接手項(xiàng)目越來越復(fù)雜的時(shí)候,有時(shí)寫完一段代碼,總感覺代碼還有優(yōu)化的空間,卻不知道從何處去下手。設(shè)計(jì)模式主要目的是提升代碼可擴(kuò)展性以及可閱讀性。 本文主要以例子的...
摘要:開發(fā)中,我們或多或少地接觸了設(shè)計(jì)模式,但是很多時(shí)候不知道自己使用了哪種設(shè)計(jì)模式或者說該使用何種設(shè)計(jì)模式。本文意在梳理常見設(shè)計(jì)模式的特點(diǎn),從而對(duì)它們有比較清晰的認(rèn)知。 showImg(https://segmentfault.com/img/remote/1460000014919705?w=640&h=280); 開發(fā)中,我們或多或少地接觸了設(shè)計(jì)模式,但是很多時(shí)候不知道自己使用了哪種設(shè)...
摘要:模式迭代器模式顧名思義,迭代器可以將對(duì)于一個(gè)聚合對(duì)象內(nèi)部元素的訪問與業(yè)務(wù)邏輯分離開。模式組合模式組合模式將對(duì)象組合成樹形結(jié)構(gòu),以表示層級(jí)結(jié)構(gòu)。重點(diǎn)是,葉結(jié)點(diǎn)與中間結(jié)點(diǎn)有統(tǒng)一借口。本文總結(jié)自設(shè)計(jì)模式與開發(fā)實(shí)踐,曾探著 模式1 - 單例模式 單例模式的核心是確保只有一個(gè)實(shí)例,并且提供全局訪問。 特點(diǎn): 滿足單一職責(zé)原則 : 使用代理模式,不在構(gòu)造函數(shù)中判斷是否已經(jīng)創(chuàng)建過該單例; 滿足惰...
摘要:什么時(shí)候需要用到單例模式呢其實(shí)單例模式在日常開發(fā)中的使用非常的廣泛,例如各種浮窗像登錄浮窗等,無論我們點(diǎn)擊多少次,都是同一個(gè)浮窗,浮窗從始至終只創(chuàng)建了一次。這種場(chǎng)景就十分適合運(yùn)用單例模式。 單例模式 什么是單例模式? 單例模式的定義:一個(gè)類僅有一個(gè)實(shí)例,并且可以在全局訪問。什么時(shí)候需要用到單例模式呢?其實(shí)單例模式在日常開發(fā)中的使用非常的廣泛,例如各種浮窗、像登錄浮窗等,無論我們點(diǎn)擊多少...
閱讀 4147·2021-11-18 13:19
閱讀 1197·2021-10-11 10:58
閱讀 3305·2019-08-29 16:39
閱讀 3164·2019-08-26 12:08
閱讀 2068·2019-08-26 11:33
閱讀 2472·2019-08-23 18:30
閱讀 1338·2019-08-23 18:21
閱讀 2545·2019-08-23 18:18