工廠模式在JS中的實(shí)踐
一. 寫在前面
工廠模式和抽象工廠在后臺代碼中的使用,相信你一定非常熟悉,所以關(guān)于概念的東西也用不著我多說。你可以用其做為類與類之間,層與層之間的解耦。工廠模式?jīng)]有什么難點(diǎn),在JS中其實(shí)思想也是一樣的,所以廢話不多說,直接上實(shí)踐的場景和代碼。
二. 場景描述
1.最近的項(xiàng)目的登陸使用了Owin認(rèn)證,所以token必須找好地方進(jìn)行存儲,鑒于token需要在請求API資源的時(shí)候放到請求頭的Authorization當(dāng)中,以便在進(jìn)入WebAPI前進(jìn)行身份驗(yàn)證。所以我不想在主流瀏覽器中的cookie中存儲token,因?yàn)檫@樣一來,每次Cookie中帶一份token,Authorization中又帶一份token.多傳輸一次不說,還讓人感到很low.這么 這么low的行為,你忍心使用嗎。所以我希望把token存儲于localStorage當(dāng)中。那么問題來了,不支持H5的瀏覽器怎么辦?
2.為了將來把所有前端資源置于CDN, 前端僅擁有html,css和js。頁面加載到瀏覽器客戶端后,所有動(dòng)態(tài)資源走AJAX,并且所有資源均跨域。那么問題又來了,跨域很容易解決,在IE8,IE9這種默認(rèn)關(guān)閉跨域功能的瀏覽器怎么辦?
三. 公共JS結(jié)構(gòu)一覽
我通常會(huì)給應(yīng)用定義一個(gè)全局Application.js。其中大概包括如下內(nèi)容。 先上整體代碼結(jié)構(gòu),供參考
四. 引入工廠思想解決問題
為了解決上述兩個(gè)問題,所以引入工廠模式,在工廠中創(chuàng)建對象,工廠中根據(jù)不同瀏覽器類型,創(chuàng)建不同對象。
也就是說在解決問題一上,在瀏覽器支持H5的時(shí)候,存儲token于localStorage。在不支持h5的瀏覽器中還是存于cookie.
所以產(chǎn)生了兩個(gè)JS對象,CookieStorageUtil對象,LocalStorageUtil對象。并且他們應(yīng)該實(shí)現(xiàn)相同的“接口”,在這里我沒有使用JS代碼來模仿接口,而是采用注釋的形式,標(biāo)注兩個(gè)對象需要實(shí)現(xiàn)相同的接口,實(shí)現(xiàn)接口中的兩個(gè)方法write()和get()。并規(guī)范代碼,下劃線開頭的為私有方法,這樣一來今后修改內(nèi)部代碼的時(shí)候,私有方法隨便改,對外部暴露的方法名稱不變就好,是不是有點(diǎn)像后臺的面向接口編程呢?其實(shí)JS也是一樣的。再多費(fèi)一句話,如果我不使用JS的function模擬類的話,是無法達(dá)到真正的方法私有,所以如果有人調(diào)用下劃線'_'開頭的私有方法,在今后私有方法有變動(dòng)的時(shí)候影響了功能,那就不是我的鍋咯?
還是上代碼靠譜:
/** * Storage Factory -Author 吳雙 cnblogs.com/tdws */ StorageUtilManager: new Object({ createStorageUtil: function () { if (window.applicationCache) { return AppUtil.LocalStorageUtil; } else { return AppUtil.CookieStorageUtil; } } }), /** * implement Storage -Author 吳雙 * write() * get() */ CookieStorageUtil: { write: function (key, dataObj) { this._clearCookie(key); //寫入的字符串 var dataObjStr = JSON.stringify(dataObj); this._setCookie(key, dataObjStr, 15); }, get: function (key) { return this._getCookie(key); }, _setCookie: function (cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); var expires = "expires=" + d.toUTCString(); var path = "path=/"; document.cookie = cname + "=" + cvalue + "; " + expires + "; " + path; }, _getCookie: function (cname) { var name = cname + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1); if (c.indexOf(name) != -1) return c.substring(name.length, c.length); } return null; }, _clearCookie: function (key) { this._setCookie(key, "", -1); } }, /** * implement Storage cnblogs.com/tdws * write() * get() */ LocalStorageUtil: { write: function (key, dataObj) { this._writeLocalStorage(key, dataObj); }, get: function (key) { return this._getFromLocalStorage(key); }, _writeLocalStorage: function (key, dataObj) { var localStorage = window.localStorage; localStorage.removeItem(key); //對象轉(zhuǎn)化為字符串,將objStr按正常的方式存入localStorage中 var dataObjStr = JSON.stringify(dataObj); localStorage.setItem(key, dataObjStr); }, _getFromLocalStorage: function (key) { var localStorage = window.localStorage; return localStorage.getItem(key); }, _removeLocalStorage: function (key) { var localStorage = window.localStorage; localStorage.removeItem(key); } }
這樣第二個(gè)問題也得到了解決,在不支持跨域的瀏覽器創(chuàng)建XDomainRequest對象來做請求,兩個(gè)HttpUtil對象依然實(shí)現(xiàn)相同的接口中的方法。在這個(gè)跨域問題上,推薦使用gayhub中的一個(gè)1.8k的JS https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
對了,為了避免使用工廠模式,使代碼調(diào)用復(fù)雜,我們可以簡化JS
AppUtil.currentHttpUtil = AppUtil.HttpUtilManager.createHttpUtil();
五. 寫在最后
所以有了這樣的方式,問題平滑的解決了,兩個(gè)StorageUtil與調(diào)用方,通過工廠StorageUtilManager完成解耦??赡苣憧赐甏a后說,不就是多了一個(gè)Manager嗎?這也很簡單啊,是啊,就是這么簡單,這就是設(shè)計(jì)模式,它僅僅是前人的經(jīng)驗(yàn)?zāi)J?,它更平滑的解決我們的實(shí)際問題。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- 詳解js產(chǎn)生對象的3種基本方式(工廠模式,構(gòu)造函數(shù)模式,原型模式)
- js面向?qū)ο笾R妱?chuàng)建對象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- JS面向?qū)ο蠡A(chǔ)講解(工廠模式、構(gòu)造函數(shù)模式、原型模式、混合模式、動(dòng)態(tài)原型模式)
- JavaScript 模式之工廠模式(Factory)應(yīng)用介紹
- javascript 模式設(shè)計(jì)之工廠模式詳細(xì)說明
- javascript 模式設(shè)計(jì)之工廠模式學(xué)習(xí)心得
- js簡單工廠模式用法實(shí)例
- JavaScript設(shè)計(jì)模式之工廠模式和構(gòu)造器模式
- javascript設(shè)計(jì)模式之工廠模式示例講解
- Javascript面向?qū)ο笤O(shè)計(jì)一 工廠模式
相關(guān)文章
JS實(shí)現(xiàn)百度搜索接口及鏈接功能實(shí)例代碼
這篇文章主要介紹了JS實(shí)現(xiàn)百度搜索接口及鏈接功能實(shí)例代碼,需要的朋友可以參考下2018-02-02javascript實(shí)現(xiàn)選中復(fù)選框后相關(guān)輸入框變灰不可用的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)選中復(fù)選框后相關(guān)輸入框變灰不可用的方法,涉及javascript針對頁面元素屬性的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08js針對ip地址、子網(wǎng)掩碼、網(wǎng)關(guān)的邏輯性判斷
這篇文章主要介紹了js針對ip地址、子網(wǎng)掩碼、網(wǎng)關(guān)的邏輯性判斷,感興趣的小伙伴們可以參考一下2016-01-01JS應(yīng)用正則表達(dá)式轉(zhuǎn)換大小寫示例
這篇文章主要介紹了JS應(yīng)用正則表達(dá)式轉(zhuǎn)換大小寫,以首字母大寫,其它字母小寫為例,喜歡的朋友可以參考下2014-09-09JavaScript使用表單元素驗(yàn)證表單的示例代碼
這篇文章主要介紹了JavaScript使用表單元素驗(yàn)證表單的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08基于RequireJS和JQuery的模塊化編程日常問題解析
本文是小編日常收集整理些有關(guān)RequireJS和JQuery的模塊化編程,感興趣的朋友一起學(xué)習(xí)吧2016-04-04JavaScript中如何校驗(yàn)接口是否重復(fù)提交
這篇文章主要為大家詳細(xì)介紹了在JavaScript中如何校驗(yàn)接口是否重復(fù)提交,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03JavaScript數(shù)字和字符串轉(zhuǎn)換示例
這篇文章主要介紹了JavaScript數(shù)字和字符串轉(zhuǎn)換的應(yīng)用,需要的朋友可以參考下2014-03-03