js最好是一種面向?qū)ο蟮恼Z言。它的出現(xiàn)時(shí)比較遲的。但是它是目前最火的腳本語言。而且,隨著近期的微信商城等頁面的興起,相信程序員和互聯(lián)網(wǎng)的從業(yè)者都知道了js正在勢(shì)頭上了。
為湖北等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及湖北網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)、湖北網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
那么,如果你想要在前端這條路上走得更遠(yuǎn),設(shè)計(jì)模式就必須要懂。下面介紹幾種常見的設(shè)計(jì)模式。
一、單例模式
單例模式也稱作為單子模式,更多的也叫做單體模式。為軟件設(shè)計(jì)中較為簡單但是最為常用的一種設(shè)計(jì)模式。 在JavaScript里,實(shí)現(xiàn)單例的方式有很多種,其中最簡單的一個(gè)方式是使用對(duì)象字面量的方法,其字面量里可以包含大量的屬性和方法:
var mySingleton = { property1: "something", property2: "something else", method1: function () { console.log('hello world'); }};
如果以后要擴(kuò)展該對(duì)象,你可以添加自己的私有成員和方法,然后使用閉包在其內(nèi)部封裝這些變量和函數(shù)聲明。只暴露你想暴露的public成員和方法,樣例代碼如下:
var mySingleton = function () { /* 這里聲明私有變量和方法 */ var privateVariable = 'something private'; function showPrivate() { console.log(privateVariable); } /* 公有變量和方法(可以訪問私有變量和方法) */ return { publicMethod: function () { showPrivate(); }, publicVar: 'the public can see this!' }; }; var single = mySingleton(); single.publicMethod(); // 輸出 'something private' console.log(single.publicVar); // 輸出 'the public can see this!'
上面的代碼很不錯(cuò)了,但如果我們想做到只有在使用的時(shí)候才初始化,那該如何做呢?為了節(jié)約資源的目的,我們可以另外一個(gè)構(gòu)造函數(shù)里來初始化這些代碼,如下:
var Singleton = (function () { var instantiated; function init() { /*這里定義單例代碼*/ return { publicMethod: function () { console.log('hello world'); }, publicProperty: 'test' }; } return { getInstance: function () { if (!instantiated) { instantiated = init(); } return instantiated; } }; })(); /*調(diào)用公有的方法來獲取實(shí)例:*/ Singleton.getInstance().publicMethod();
二、工廠模式
工廠模式是由一個(gè)方法來決定到底要?jiǎng)?chuàng)建哪個(gè)類的實(shí)例, 而這些實(shí)例經(jīng)常都擁有相同的接口. 這種模式主要用在所實(shí)例化的類型在編譯期并不能確定, 而是在執(zhí)行期決定的情況。 說的通俗點(diǎn),就像公司茶水間的飲料機(jī),要咖啡還是牛奶取決于你按哪個(gè)按鈕。
實(shí)例:
function A( name ){ this.name = name; } function ObjectFactory(){ var obj = {}, Constructor = Array.prototype.shift.call( arguments ); obj.__proto__ = typeof Constructor .prototype === 'number' ? Object.prototype : Constructor .prototype; var ret = Constructor.apply( obj, arguments ); return typeof ret === 'object' ? ret : obj; } var a = ObjectFactory( A, 'svenzeng' ); alert ( a.name ); //svenzeng
這段代碼來自es5的new和構(gòu)造器的相關(guān)說明, 可以看到,所謂的new, 本身只是一個(gè)對(duì)象的復(fù)制和改寫過程, 而具體會(huì)生成什么是由調(diào)用ObjectFactory時(shí)傳進(jìn)去的參數(shù)所決定的。
三、 適配模式
簡單的說,適配模式主要是為了解決一些接口不兼容產(chǎn)生的解決方法。借助于適配器我們可以在不修改這些不兼容接口的情況下給使用者提供統(tǒng)一的包裝過的適配接口。表面上又感覺和之前的門面模式比較像,均是對(duì)其他對(duì)象或者接口進(jìn)行包裝再呈現(xiàn),而適配器模式偏向的是解決兼容性問題,門面模式則偏向方便性為原則。
比如一個(gè)簡單的學(xué)生查詢學(xué)科成績的方法:
function selectScore( name, id, course_id ){ // arguments 姓名 學(xué)號(hào) 課程id ... }
當(dāng)我需要一個(gè)班級(jí)某門學(xué)科的整體成績列表,而我手上只有每個(gè)學(xué)生如下的數(shù)據(jù)
[ { name: 'lily', studentID: '0911' }, { name: 'suny', studentID: '0912' }, ... ]
我需要查詢 英語 其課程ID為 101,那么對(duì)于該任務(wù),寫一個(gè)適配器方式是很恰當(dāng)不過的
function selectEnglishScore( stutentObj ){ selectScore( stutentObj.name, stutentObj.studentID , 101); }
這是一個(gè)最簡單的關(guān)于適配器來處理參數(shù)方面兼容的形式。 其實(shí)簡單的來說,適配器模式意義上很簡單 - 適配,解決兼容問題。
例子二,比如你覺得jquery里邊的$選擇器需要改成$id才能和你的項(xiàng)目搭配,那么這時(shí)候?qū)懸粋€(gè)方法,將$轉(zhuǎn)換成$id就很輕松了。如下:
$id = function( id ){ return jQuery( '#' + id )[0]; }
四、外觀模式
外觀模式(門面模式),是一種相對(duì)簡單而又無處不在的模式。外觀模式提供一個(gè)高層接口,這個(gè)接口使得客戶端或子系統(tǒng)更加方便調(diào)用。 用一段再簡單不過的代碼來表示:
var getName = function(){ return ''svenzeng" } var getSex = function(){ return 'man' }
如果你需要分別調(diào)用getName和getSex函數(shù). 那可以用一個(gè)更高層的接口getUserInfo來調(diào)用.:
var getUserInfo = function(){ var info = a() + b(); return info; }
也許你會(huì)問為什么一開始不把getName和getSex的代碼寫到一起, 比如這樣:
var getNameAndSex = function(){ return 'svenzeng" + "man"; }
答案是顯而易見的,飯?zhí)玫某床藥煾挡粫?huì)因?yàn)槟泐A(yù)定了一份燒鴨和一份白菜就把這兩樣菜炒在一個(gè)鍋里。他更愿意給你提供一個(gè)燒鴨飯?zhí)撞汀M瑯釉诔绦蛟O(shè)計(jì)中,我們需要保證函數(shù)或者對(duì)象盡可能的處在一個(gè)合理粒度,畢竟不是每個(gè)人喜歡吃燒鴨的同時(shí)又剛好喜歡吃白菜。 外觀模式還有一個(gè)好處是可以對(duì)用戶隱藏真正的實(shí)現(xiàn)細(xì)節(jié),用戶只關(guān)心最高層的接口。比如在燒鴨飯?zhí)撞偷墓适轮校悴⒉魂P(guān)心師傅是先做燒鴨還是先炒白菜,你也不關(guān)心那只鴨子是在哪里成長的。
最后寫個(gè)我們都用過的外觀模式例子:
var stopEvent = function( e ){ //同時(shí)阻止事件默認(rèn)行為和冒泡 e.stopPropagation(); e.preventDefault(); }
好了,今天的額設(shè)計(jì)模式就先到這里。如果大家想要了解更多的設(shè)計(jì)模式可以去湯姆大叔的博客欣賞哦。還有,這里的很多的設(shè)計(jì)模式其實(shí)都是將解決問題的方法細(xì)化了的說法,如果去看一下prototype或者jquery都會(huì)知道,其實(shí)里邊的代碼很多都用到了設(shè)計(jì)模式的。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持創(chuàng)新互聯(lián)!